Mercurial > pub > ImplabNet
annotate Implab.ServiceHost/Unity/TypeResolver.cs @ 278:6691aff01de1 v3
Implab: added XmlDefaultSeializer (SerializersPool is now obsolete)
Implab.ServiceHost: rewritten TypeReference (added support for nested types), stable API
author | cin |
---|---|
date | Thu, 03 May 2018 09:59:44 +0300 |
parents | 963b17c275be |
children | 8714471e8d78 |
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) { |
6691aff01de1
Implab: added XmlDefaultSeializer (SerializersPool is now obsolete)
cin
parents:
277
diff
changeset
|
30 var typeReference = TypeReference.Parse(typeSpec); |
6691aff01de1
Implab: added XmlDefaultSeializer (SerializersPool is now obsolete)
cin
parents:
277
diff
changeset
|
31 return Resolve(typeReference, throwOnFail); |
6691aff01de1
Implab: added XmlDefaultSeializer (SerializersPool is now obsolete)
cin
parents:
277
diff
changeset
|
32 } |
6691aff01de1
Implab: added XmlDefaultSeializer (SerializersPool is now obsolete)
cin
parents:
277
diff
changeset
|
33 |
270 | 34 LinkedListNode<string> m_insertAt; |
35 | |
36 readonly TypeResolver m_parent; | |
37 | |
38 public TypeResolver() : this(null) { | |
39 } | |
40 | |
41 public TypeResolver(TypeResolver parent) { | |
272 | 42 m_parent = parent; |
270 | 43 m_insertAt = new LinkedListNode<string>(string.Empty); |
44 m_namespases.AddFirst(m_insertAt); | |
45 } | |
46 | |
47 public void AddNamespace(string ns) { | |
48 Safe.ArgumentMatch(ns, nameof(ns), _nsRx); | |
49 if (m_insertAt != null) | |
50 m_namespases.AddAfter(m_insertAt, ns); | |
51 else | |
52 m_namespases.AddFirst(ns); | |
53 } | |
54 | |
55 public void AddMapping(string typeName, Type type) { | |
56 Safe.ArgumentNotEmpty(typeName, nameof(typeName)); | |
57 Safe.ArgumentNotNull(type, nameof(type)); | |
58 | |
59 m_cache[typeName] = type; | |
60 } | |
61 | |
278
6691aff01de1
Implab: added XmlDefaultSeializer (SerializersPool is now obsolete)
cin
parents:
277
diff
changeset
|
62 Type ProbeInNamespaces(string localName) { |
270 | 63 |
64 Type resolved; | |
278
6691aff01de1
Implab: added XmlDefaultSeializer (SerializersPool is now obsolete)
cin
parents:
277
diff
changeset
|
65 if (!m_cache.TryGetValue(localName, out resolved)) { |
6691aff01de1
Implab: added XmlDefaultSeializer (SerializersPool is now obsolete)
cin
parents:
277
diff
changeset
|
66 foreach (var ns in m_namespases) { |
6691aff01de1
Implab: added XmlDefaultSeializer (SerializersPool is now obsolete)
cin
parents:
277
diff
changeset
|
67 var typeName = string.IsNullOrEmpty(ns) ? localName : $"{ns}.{localName}"; |
6691aff01de1
Implab: added XmlDefaultSeializer (SerializersPool is now obsolete)
cin
parents:
277
diff
changeset
|
68 resolved = Probe(typeName); |
6691aff01de1
Implab: added XmlDefaultSeializer (SerializersPool is now obsolete)
cin
parents:
277
diff
changeset
|
69 if (resolved != null) { |
6691aff01de1
Implab: added XmlDefaultSeializer (SerializersPool is now obsolete)
cin
parents:
277
diff
changeset
|
70 Log($"Probe '{localName}' -> '{resolved.FullName}'"); |
6691aff01de1
Implab: added XmlDefaultSeializer (SerializersPool is now obsolete)
cin
parents:
277
diff
changeset
|
71 break; |
6691aff01de1
Implab: added XmlDefaultSeializer (SerializersPool is now obsolete)
cin
parents:
277
diff
changeset
|
72 } |
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 if (resolved == null && m_parent != null) |
6691aff01de1
Implab: added XmlDefaultSeializer (SerializersPool is now obsolete)
cin
parents:
277
diff
changeset
|
76 resolved = m_parent.ProbeInNamespaces(localName); |
6691aff01de1
Implab: added XmlDefaultSeializer (SerializersPool is now obsolete)
cin
parents:
277
diff
changeset
|
77 |
6691aff01de1
Implab: added XmlDefaultSeializer (SerializersPool is now obsolete)
cin
parents:
277
diff
changeset
|
78 if(resolved == null) |
6691aff01de1
Implab: added XmlDefaultSeializer (SerializersPool is now obsolete)
cin
parents:
277
diff
changeset
|
79 Log($"Probe '{localName}' failed"); |
6691aff01de1
Implab: added XmlDefaultSeializer (SerializersPool is now obsolete)
cin
parents:
277
diff
changeset
|
80 |
6691aff01de1
Implab: added XmlDefaultSeializer (SerializersPool is now obsolete)
cin
parents:
277
diff
changeset
|
81 m_cache[localName] = resolved; |
270 | 82 } |
83 | |
84 return resolved; | |
85 } | |
86 | |
87 Type Probe(string typeName) { | |
88 var assemblies = AppDomain.CurrentDomain.GetAssemblies(); | |
89 | |
277 | 90 foreach (var assembly in assemblies) { |
270 | 91 var type = assembly.GetType(typeName); |
92 if (type != null) | |
93 return type; | |
94 } | |
95 return null; | |
96 } | |
97 } | |
98 } |