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
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
270
ade80d94dfb5 Working on Unity container xml configuration
cin
parents:
diff changeset
1 using System;
ade80d94dfb5 Working on Unity container xml configuration
cin
parents:
diff changeset
2 using System.Collections.Generic;
ade80d94dfb5 Working on Unity container xml configuration
cin
parents:
diff changeset
3 using System.Linq;
ade80d94dfb5 Working on Unity container xml configuration
cin
parents:
diff changeset
4 using System.Text;
ade80d94dfb5 Working on Unity container xml configuration
cin
parents:
diff changeset
5 using System.Text.RegularExpressions;
ade80d94dfb5 Working on Unity container xml configuration
cin
parents:
diff changeset
6 using Implab.Diagnostics;
ade80d94dfb5 Working on Unity container xml configuration
cin
parents:
diff changeset
7
277
963b17c275be Refactoring
cin
parents: 272
diff changeset
8 namespace Implab.ServiceHost.Unity {
278
6691aff01de1 Implab: added XmlDefaultSeializer (SerializersPool is now obsolete)
cin
parents: 277
diff changeset
9 using System.Diagnostics;
270
ade80d94dfb5 Working on Unity container xml configuration
cin
parents:
diff changeset
10 using static Trace<TypeResolver>;
277
963b17c275be Refactoring
cin
parents: 272
diff changeset
11 public class TypeResolver {
270
ade80d94dfb5 Working on Unity container xml configuration
cin
parents:
diff changeset
12 readonly Dictionary<string, Type> m_cache = new Dictionary<string, Type>();
ade80d94dfb5 Working on Unity container xml configuration
cin
parents:
diff changeset
13
ade80d94dfb5 Working on Unity container xml configuration
cin
parents:
diff changeset
14 Regex _nsRx = new Regex(@"^\w+(\.\w+)*$", RegexOptions.Compiled);
ade80d94dfb5 Working on Unity container xml configuration
cin
parents:
diff changeset
15 readonly LinkedList<string> m_namespases = new LinkedList<string>();
ade80d94dfb5 Working on Unity container xml configuration
cin
parents:
diff changeset
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
ade80d94dfb5 Working on Unity container xml configuration
cin
parents:
diff changeset
34 LinkedListNode<string> m_insertAt;
ade80d94dfb5 Working on Unity container xml configuration
cin
parents:
diff changeset
35
ade80d94dfb5 Working on Unity container xml configuration
cin
parents:
diff changeset
36 readonly TypeResolver m_parent;
ade80d94dfb5 Working on Unity container xml configuration
cin
parents:
diff changeset
37
ade80d94dfb5 Working on Unity container xml configuration
cin
parents:
diff changeset
38 public TypeResolver() : this(null) {
ade80d94dfb5 Working on Unity container xml configuration
cin
parents:
diff changeset
39 }
ade80d94dfb5 Working on Unity container xml configuration
cin
parents:
diff changeset
40
ade80d94dfb5 Working on Unity container xml configuration
cin
parents:
diff changeset
41 public TypeResolver(TypeResolver parent) {
272
9d1cca834b05 preview version of Unity xml configuration
cin
parents: 270
diff changeset
42 m_parent = parent;
270
ade80d94dfb5 Working on Unity container xml configuration
cin
parents:
diff changeset
43 m_insertAt = new LinkedListNode<string>(string.Empty);
ade80d94dfb5 Working on Unity container xml configuration
cin
parents:
diff changeset
44 m_namespases.AddFirst(m_insertAt);
ade80d94dfb5 Working on Unity container xml configuration
cin
parents:
diff changeset
45 }
ade80d94dfb5 Working on Unity container xml configuration
cin
parents:
diff changeset
46
ade80d94dfb5 Working on Unity container xml configuration
cin
parents:
diff changeset
47 public void AddNamespace(string ns) {
ade80d94dfb5 Working on Unity container xml configuration
cin
parents:
diff changeset
48 Safe.ArgumentMatch(ns, nameof(ns), _nsRx);
ade80d94dfb5 Working on Unity container xml configuration
cin
parents:
diff changeset
49 if (m_insertAt != null)
ade80d94dfb5 Working on Unity container xml configuration
cin
parents:
diff changeset
50 m_namespases.AddAfter(m_insertAt, ns);
ade80d94dfb5 Working on Unity container xml configuration
cin
parents:
diff changeset
51 else
ade80d94dfb5 Working on Unity container xml configuration
cin
parents:
diff changeset
52 m_namespases.AddFirst(ns);
ade80d94dfb5 Working on Unity container xml configuration
cin
parents:
diff changeset
53 }
ade80d94dfb5 Working on Unity container xml configuration
cin
parents:
diff changeset
54
ade80d94dfb5 Working on Unity container xml configuration
cin
parents:
diff changeset
55 public void AddMapping(string typeName, Type type) {
ade80d94dfb5 Working on Unity container xml configuration
cin
parents:
diff changeset
56 Safe.ArgumentNotEmpty(typeName, nameof(typeName));
ade80d94dfb5 Working on Unity container xml configuration
cin
parents:
diff changeset
57 Safe.ArgumentNotNull(type, nameof(type));
ade80d94dfb5 Working on Unity container xml configuration
cin
parents:
diff changeset
58
ade80d94dfb5 Working on Unity container xml configuration
cin
parents:
diff changeset
59 m_cache[typeName] = type;
ade80d94dfb5 Working on Unity container xml configuration
cin
parents:
diff changeset
60 }
ade80d94dfb5 Working on Unity container xml configuration
cin
parents:
diff changeset
61
278
6691aff01de1 Implab: added XmlDefaultSeializer (SerializersPool is now obsolete)
cin
parents: 277
diff changeset
62 Type ProbeInNamespaces(string localName) {
270
ade80d94dfb5 Working on Unity container xml configuration
cin
parents:
diff changeset
63
ade80d94dfb5 Working on Unity container xml configuration
cin
parents:
diff changeset
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
ade80d94dfb5 Working on Unity container xml configuration
cin
parents:
diff changeset
82 }
ade80d94dfb5 Working on Unity container xml configuration
cin
parents:
diff changeset
83
ade80d94dfb5 Working on Unity container xml configuration
cin
parents:
diff changeset
84 return resolved;
ade80d94dfb5 Working on Unity container xml configuration
cin
parents:
diff changeset
85 }
ade80d94dfb5 Working on Unity container xml configuration
cin
parents:
diff changeset
86
ade80d94dfb5 Working on Unity container xml configuration
cin
parents:
diff changeset
87 Type Probe(string typeName) {
ade80d94dfb5 Working on Unity container xml configuration
cin
parents:
diff changeset
88 var assemblies = AppDomain.CurrentDomain.GetAssemblies();
ade80d94dfb5 Working on Unity container xml configuration
cin
parents:
diff changeset
89
277
963b17c275be Refactoring
cin
parents: 272
diff changeset
90 foreach (var assembly in assemblies) {
270
ade80d94dfb5 Working on Unity container xml configuration
cin
parents:
diff changeset
91 var type = assembly.GetType(typeName);
ade80d94dfb5 Working on Unity container xml configuration
cin
parents:
diff changeset
92 if (type != null)
ade80d94dfb5 Working on Unity container xml configuration
cin
parents:
diff changeset
93 return type;
ade80d94dfb5 Working on Unity container xml configuration
cin
parents:
diff changeset
94 }
ade80d94dfb5 Working on Unity container xml configuration
cin
parents:
diff changeset
95 return null;
ade80d94dfb5 Working on Unity container xml configuration
cin
parents:
diff changeset
96 }
ade80d94dfb5 Working on Unity container xml configuration
cin
parents:
diff changeset
97 }
ade80d94dfb5 Working on Unity container xml configuration
cin
parents:
diff changeset
98 }