Mercurial > pub > ImplabNet
annotate 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 |
| rev | line source |
|---|---|
| 270 | 1 using System; |
| 2 using System.Collections.Generic; | |
| 3 using System.Linq; | |
| 4 using System.Text; | |
| 5 using System.Text.RegularExpressions; | |
| 6 using Implab.Diagnostics; | |
| 7 | |
| 277 | 8 namespace Implab.ServiceHost.Unity { |
|
278
6691aff01de1
Implab: added XmlDefaultSeializer (SerializersPool is now obsolete)
cin
parents:
277
diff
changeset
|
9 using System.Diagnostics; |
| 270 | 10 using static Trace<TypeResolver>; |
| 277 | 11 public class TypeResolver { |
| 270 | 12 readonly Dictionary<string, Type> m_cache = new Dictionary<string, Type>(); |
| 13 | |
| 14 Regex _nsRx = new Regex(@"^\w+(\.\w+)*$", RegexOptions.Compiled); | |
| 15 readonly LinkedList<string> m_namespases = new LinkedList<string>(); | |
| 16 | |
|
278
6691aff01de1
Implab: added XmlDefaultSeializer (SerializersPool is now obsolete)
cin
parents:
277
diff
changeset
|
17 internal Type Resolve(string ns, string typeName) { |
|
6691aff01de1
Implab: added XmlDefaultSeializer (SerializersPool is now obsolete)
cin
parents:
277
diff
changeset
|
18 var fullName = string.IsNullOrEmpty(ns) ? typeName : $"{ns}.{typeName}"; |
|
6691aff01de1
Implab: added XmlDefaultSeializer (SerializersPool is now obsolete)
cin
parents:
277
diff
changeset
|
19 |
|
6691aff01de1
Implab: added XmlDefaultSeializer (SerializersPool is now obsolete)
cin
parents:
277
diff
changeset
|
20 return ProbeInNamespaces(fullName); |
|
6691aff01de1
Implab: added XmlDefaultSeializer (SerializersPool is now obsolete)
cin
parents:
277
diff
changeset
|
21 } |
|
6691aff01de1
Implab: added XmlDefaultSeializer (SerializersPool is now obsolete)
cin
parents:
277
diff
changeset
|
22 |
|
6691aff01de1
Implab: added XmlDefaultSeializer (SerializersPool is now obsolete)
cin
parents:
277
diff
changeset
|
23 public Type Resolve(TypeReference typeReference, bool throwOnFail) { |
|
6691aff01de1
Implab: added XmlDefaultSeializer (SerializersPool is now obsolete)
cin
parents:
277
diff
changeset
|
24 var context = new TypeResolutionContext(this, throwOnFail); |
|
6691aff01de1
Implab: added XmlDefaultSeializer (SerializersPool is now obsolete)
cin
parents:
277
diff
changeset
|
25 typeReference.Visit(context); |
|
6691aff01de1
Implab: added XmlDefaultSeializer (SerializersPool is now obsolete)
cin
parents:
277
diff
changeset
|
26 return context.MakeType(); |
|
6691aff01de1
Implab: added XmlDefaultSeializer (SerializersPool is now obsolete)
cin
parents:
277
diff
changeset
|
27 } |
|
6691aff01de1
Implab: added XmlDefaultSeializer (SerializersPool is now obsolete)
cin
parents:
277
diff
changeset
|
28 |
|
6691aff01de1
Implab: added XmlDefaultSeializer (SerializersPool is now obsolete)
cin
parents:
277
diff
changeset
|
29 public Type Resolve(string typeSpec, bool throwOnFail) { |
| 279 | 30 Safe.ArgumentNotEmpty(typeSpec, nameof(typeSpec)); |
|
278
6691aff01de1
Implab: added XmlDefaultSeializer (SerializersPool is now obsolete)
cin
parents:
277
diff
changeset
|
31 var typeReference = TypeReference.Parse(typeSpec); |
|
6691aff01de1
Implab: added XmlDefaultSeializer (SerializersPool is now obsolete)
cin
parents:
277
diff
changeset
|
32 return Resolve(typeReference, throwOnFail); |
|
6691aff01de1
Implab: added XmlDefaultSeializer (SerializersPool is now obsolete)
cin
parents:
277
diff
changeset
|
33 } |
|
6691aff01de1
Implab: added XmlDefaultSeializer (SerializersPool is now obsolete)
cin
parents:
277
diff
changeset
|
34 |
| 270 | 35 LinkedListNode<string> m_insertAt; |
| 36 | |
| 37 readonly TypeResolver m_parent; | |
| 38 | |
| 39 public TypeResolver() : this(null) { | |
| 40 } | |
| 41 | |
| 42 public TypeResolver(TypeResolver parent) { | |
| 272 | 43 m_parent = parent; |
| 270 | 44 m_insertAt = new LinkedListNode<string>(string.Empty); |
| 45 m_namespases.AddFirst(m_insertAt); | |
| 46 } | |
| 47 | |
| 48 public void AddNamespace(string ns) { | |
| 49 Safe.ArgumentMatch(ns, nameof(ns), _nsRx); | |
| 50 if (m_insertAt != null) | |
| 51 m_namespases.AddAfter(m_insertAt, ns); | |
| 52 else | |
| 53 m_namespases.AddFirst(ns); | |
| 54 } | |
| 55 | |
| 56 public void AddMapping(string typeName, Type type) { | |
| 57 Safe.ArgumentNotEmpty(typeName, nameof(typeName)); | |
| 58 Safe.ArgumentNotNull(type, nameof(type)); | |
| 59 | |
| 60 m_cache[typeName] = type; | |
| 61 } | |
| 62 | |
|
278
6691aff01de1
Implab: added XmlDefaultSeializer (SerializersPool is now obsolete)
cin
parents:
277
diff
changeset
|
63 Type ProbeInNamespaces(string localName) { |
| 270 | 64 |
| 65 Type resolved; | |
|
278
6691aff01de1
Implab: added XmlDefaultSeializer (SerializersPool is now obsolete)
cin
parents:
277
diff
changeset
|
66 if (!m_cache.TryGetValue(localName, out resolved)) { |
|
6691aff01de1
Implab: added XmlDefaultSeializer (SerializersPool is now obsolete)
cin
parents:
277
diff
changeset
|
67 foreach (var ns in m_namespases) { |
|
6691aff01de1
Implab: added XmlDefaultSeializer (SerializersPool is now obsolete)
cin
parents:
277
diff
changeset
|
68 var typeName = string.IsNullOrEmpty(ns) ? localName : $"{ns}.{localName}"; |
|
6691aff01de1
Implab: added XmlDefaultSeializer (SerializersPool is now obsolete)
cin
parents:
277
diff
changeset
|
69 resolved = Probe(typeName); |
|
6691aff01de1
Implab: added XmlDefaultSeializer (SerializersPool is now obsolete)
cin
parents:
277
diff
changeset
|
70 if (resolved != null) { |
|
6691aff01de1
Implab: added XmlDefaultSeializer (SerializersPool is now obsolete)
cin
parents:
277
diff
changeset
|
71 Log($"Probe '{localName}' -> '{resolved.FullName}'"); |
|
6691aff01de1
Implab: added XmlDefaultSeializer (SerializersPool is now obsolete)
cin
parents:
277
diff
changeset
|
72 break; |
|
6691aff01de1
Implab: added XmlDefaultSeializer (SerializersPool is now obsolete)
cin
parents:
277
diff
changeset
|
73 } |
|
6691aff01de1
Implab: added XmlDefaultSeializer (SerializersPool is now obsolete)
cin
parents:
277
diff
changeset
|
74 } |
|
6691aff01de1
Implab: added XmlDefaultSeializer (SerializersPool is now obsolete)
cin
parents:
277
diff
changeset
|
75 |
|
6691aff01de1
Implab: added XmlDefaultSeializer (SerializersPool is now obsolete)
cin
parents:
277
diff
changeset
|
76 if (resolved == null && m_parent != null) |
|
6691aff01de1
Implab: added XmlDefaultSeializer (SerializersPool is now obsolete)
cin
parents:
277
diff
changeset
|
77 resolved = m_parent.ProbeInNamespaces(localName); |
|
6691aff01de1
Implab: added XmlDefaultSeializer (SerializersPool is now obsolete)
cin
parents:
277
diff
changeset
|
78 |
|
6691aff01de1
Implab: added XmlDefaultSeializer (SerializersPool is now obsolete)
cin
parents:
277
diff
changeset
|
79 if(resolved == null) |
|
6691aff01de1
Implab: added XmlDefaultSeializer (SerializersPool is now obsolete)
cin
parents:
277
diff
changeset
|
80 Log($"Probe '{localName}' failed"); |
|
6691aff01de1
Implab: added XmlDefaultSeializer (SerializersPool is now obsolete)
cin
parents:
277
diff
changeset
|
81 |
|
6691aff01de1
Implab: added XmlDefaultSeializer (SerializersPool is now obsolete)
cin
parents:
277
diff
changeset
|
82 m_cache[localName] = resolved; |
| 270 | 83 } |
| 84 | |
| 85 return resolved; | |
| 86 } | |
| 87 | |
| 88 Type Probe(string typeName) { | |
| 89 var assemblies = AppDomain.CurrentDomain.GetAssemblies(); | |
| 90 | |
| 277 | 91 foreach (var assembly in assemblies) { |
| 270 | 92 var type = assembly.GetType(typeName); |
| 93 if (type != null) | |
| 94 return type; | |
| 95 } | |
| 96 return null; | |
| 97 } | |
| 98 } | |
| 99 } |
