Mercurial > pub > ImplabNet
view Implab.ServiceHost/Unity/TypeResolver.cs @ 280:f07be402ab02 v3
Added Trace<T>.Debug(...) method for debug messages
Added ContainerBuilde.LoadConfig(Uri) method
author | cin |
---|---|
date | Fri, 25 May 2018 19:15:26 +0300 |
parents | 8714471e8d78 |
children |
line wrap: on
line source
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Text.RegularExpressions; using Implab.Diagnostics; namespace Implab.ServiceHost.Unity { using System.Diagnostics; using static Trace<TypeResolver>; public class TypeResolver { readonly Dictionary<string, Type> m_cache = new Dictionary<string, Type>(); Regex _nsRx = new Regex(@"^\w+(\.\w+)*$", RegexOptions.Compiled); readonly LinkedList<string> m_namespases = new LinkedList<string>(); internal Type Resolve(string ns, string typeName) { var fullName = string.IsNullOrEmpty(ns) ? typeName : $"{ns}.{typeName}"; return ProbeInNamespaces(fullName); } public Type Resolve(TypeReference typeReference, bool throwOnFail) { var context = new TypeResolutionContext(this, throwOnFail); typeReference.Visit(context); return context.MakeType(); } public Type Resolve(string typeSpec, bool throwOnFail) { Safe.ArgumentNotEmpty(typeSpec, nameof(typeSpec)); var typeReference = TypeReference.Parse(typeSpec); return Resolve(typeReference, throwOnFail); } LinkedListNode<string> m_insertAt; readonly TypeResolver m_parent; public TypeResolver() : this(null) { } public TypeResolver(TypeResolver parent) { m_parent = parent; m_insertAt = new LinkedListNode<string>(string.Empty); m_namespases.AddFirst(m_insertAt); } public void AddNamespace(string ns) { Safe.ArgumentMatch(ns, nameof(ns), _nsRx); if (m_insertAt != null) m_namespases.AddAfter(m_insertAt, ns); else m_namespases.AddFirst(ns); } public void AddMapping(string typeName, Type type) { Safe.ArgumentNotEmpty(typeName, nameof(typeName)); Safe.ArgumentNotNull(type, nameof(type)); m_cache[typeName] = type; } Type ProbeInNamespaces(string localName) { Type resolved; if (!m_cache.TryGetValue(localName, out resolved)) { foreach (var ns in m_namespases) { var typeName = string.IsNullOrEmpty(ns) ? localName : $"{ns}.{localName}"; resolved = Probe(typeName); if (resolved != null) { Log($"Probe '{localName}' -> '{resolved.FullName}'"); break; } } if (resolved == null && m_parent != null) resolved = m_parent.ProbeInNamespaces(localName); if(resolved == null) Log($"Probe '{localName}' failed"); m_cache[localName] = resolved; } return resolved; } Type Probe(string typeName) { var assemblies = AppDomain.CurrentDomain.GetAssemblies(); foreach (var assembly in assemblies) { var type = assembly.GetType(typeName); if (type != null) return type; } return null; } } }