comparison Implab.ServiceHost/Unity/TypeResolver.cs @ 277:963b17c275be v3

Refactoring Added <array> element to injection parameters Working on registrations of factories
author cin
date Sat, 28 Apr 2018 18:48:09 +0300
parents 9d1cca834b05
children 6691aff01de1
comparison
equal deleted inserted replaced
276:b4e0f81c7425 277:963b17c275be
3 using System.Linq; 3 using System.Linq;
4 using System.Text; 4 using System.Text;
5 using System.Text.RegularExpressions; 5 using System.Text.RegularExpressions;
6 using Implab.Diagnostics; 6 using Implab.Diagnostics;
7 7
8 namespace Implab.ServiceHost.Unity 8 namespace Implab.ServiceHost.Unity {
9 {
10 using static Trace<TypeResolver>; 9 using static Trace<TypeResolver>;
11 public class TypeResolver 10 public class TypeResolver {
12 {
13 readonly Dictionary<string, Type> m_cache = new Dictionary<string, Type>(); 11 readonly Dictionary<string, Type> m_cache = new Dictionary<string, Type>();
14 12
15 Regex _nsRx = new Regex(@"^\w+(\.\w+)*$", RegexOptions.Compiled); 13 Regex _nsRx = new Regex(@"^\w+(\.\w+)*$", RegexOptions.Compiled);
16 readonly LinkedList<string> m_namespases = new LinkedList<string>(); 14 readonly LinkedList<string> m_namespases = new LinkedList<string>();
17 15
47 public Type Resolve(TypeReference reference) { 45 public Type Resolve(TypeReference reference) {
48 var args = reference.IsGeneric && !reference.IsOpenGeneric ? reference.GenericParameters?.Select(Resolve).ToArray() : null; 46 var args = reference.IsGeneric && !reference.IsOpenGeneric ? reference.GenericParameters?.Select(Resolve).ToArray() : null;
49 var argc = reference.IsGeneric ? reference.GenericParameters.Length : 0; 47 var argc = reference.IsGeneric ? reference.GenericParameters.Length : 0;
50 48
51 Type resolved; 49 Type resolved;
52 if(!m_cache.TryGetValue(reference.ToString(), out resolved)) { 50 if (!m_cache.TryGetValue(reference.ToString(), out resolved)) {
53 resolved = ResolveInternal(reference, args, argc); 51 resolved = ResolveInternal(reference, args, argc);
54 if (resolved == null) 52 if (resolved == null)
55 throw new Exception($"Failed to resolve {reference}"); 53 throw new Exception($"Failed to resolve {reference}");
56 m_cache[reference.ToString()] = resolved; 54 m_cache[reference.ToString()] = resolved;
57 } 55 }
63 return Resolve(TypeReference.Parse(typeSpec)); 61 return Resolve(TypeReference.Parse(typeSpec));
64 } 62 }
65 63
66 Type ResolveInternal(TypeReference reference, Type[] args, int argc) { 64 Type ResolveInternal(TypeReference reference, Type[] args, int argc) {
67 var resolved = ProbeInNamespaces( 65 var resolved = ProbeInNamespaces(
68 String.Join(".", new [] { reference.Namespace, reference.TypeName }.Where(x => !string.IsNullOrEmpty(x)) ), 66 String.Join(".", new[] { reference.Namespace, reference.TypeName }.Where(x => !string.IsNullOrEmpty(x))),
69 args, 67 args,
70 argc, 68 argc,
71 reference.IsArray, 69 reference.IsArray,
72 reference.ToString() 70 reference.ToString()
73 ); 71 );
74 72
75 if (resolved == null && m_parent != null) 73 if (resolved == null && m_parent != null)
76 resolved = m_parent.Resolve(reference); 74 resolved = m_parent.ResolveInternal(reference, args, argc);
77 75
78 return resolved; 76 return resolved;
79 } 77 }
80 78
81 public Type ProbeInNamespaces(string localName, Type[] args, int argc, bool isArray, string referenceName) { 79 public Type ProbeInNamespaces(string localName, Type[] args, int argc, bool isArray, string referenceName) {
82 foreach (var ns in m_namespases) { 80 foreach (var ns in m_namespases) {
83 var typeName = FormatName(new [] { ns, localName}, argc, args, isArray); 81 var typeName = FormatName(new[] { ns, localName }, argc);
84 82
85 var resolved = Probe(typeName); 83 var resolved = Probe(typeName);
86 if (resolved != null) { 84 if (resolved != null) {
85 if (args != null && args.Length > 0) {
86 resolved = resolved.MakeGenericType(args);
87 }
88
89 if (isArray)
90 resolved = resolved.MakeArrayType();
91
87 Log("Probe succeed {0} in '{1}': {2} -> {3}", referenceName, ns, typeName, resolved.AssemblyQualifiedName); 92 Log("Probe succeed {0} in '{1}': {2} -> {3}", referenceName, ns, typeName, resolved.AssemblyQualifiedName);
88 return resolved; 93 return resolved;
89 } else { 94 } else {
90 Log("Probe failed {0} in '{1}': {2}", referenceName, ns, typeName); 95 Log("Probe failed {0} in '{1}': {2}", referenceName, ns, typeName);
91 } 96 }
95 } 100 }
96 101
97 Type Probe(string typeName) { 102 Type Probe(string typeName) {
98 var assemblies = AppDomain.CurrentDomain.GetAssemblies(); 103 var assemblies = AppDomain.CurrentDomain.GetAssemblies();
99 104
100 foreach(var assembly in assemblies) { 105 foreach (var assembly in assemblies) {
101 var type = assembly.GetType(typeName); 106 var type = assembly.GetType(typeName);
102 if (type != null) 107 if (type != null)
103 return type; 108 return type;
104 } 109 }
105 return null; 110 return null;
106 } 111 }
107 112
108 string FormatName(string[] parts, int argc, Type[] args, bool isArray) { 113 string FormatName(string[] parts, int argc) {
109 var builder = new StringBuilder(); 114 var builder = new StringBuilder();
110 115
111 builder.Append(String.Join(".", parts.Where(x => !string.IsNullOrEmpty(x)))); 116 builder.Append(String.Join(".", parts.Where(x => !string.IsNullOrEmpty(x))));
112 if (argc > 0) { 117 if (argc > 0) {
113 builder.Append('`'); 118 builder.Append('`');
114 builder.Append(argc); 119 builder.Append(argc);
115 } 120 }
116 121
117 if (args!= null && args.Length > 0) { 122 return builder.ToString();
118 builder.Append('[');
119 builder.Append(string.Join(",", args.Select(x => $"[{x.AssemblyQualifiedName}]")));
120 builder.Append(']');
121 }
122
123 if(isArray)
124 builder.Append("[]");
125
126 return builder.ToString();
127 } 123 }
128 } 124 }
129 } 125 }