Mercurial > pub > ImplabNet
comparison Implab.ServiceHost/Unity/ConfigurationContext.cs @ 270:ade80d94dfb5 v3
Working on Unity container xml configuration
author | cin |
---|---|
date | Wed, 25 Apr 2018 04:44:40 +0300 |
parents | ff581cff7003 |
children | 9d1cca834b05 |
comparison
equal
deleted
inserted
replaced
269:ff581cff7003 | 270:ade80d94dfb5 |
---|---|
6 namespace Implab.ServiceHost.Unity { | 6 namespace Implab.ServiceHost.Unity { |
7 using System.Linq; | 7 using System.Linq; |
8 using System.Reflection; | 8 using System.Reflection; |
9 using System.Text; | 9 using System.Text; |
10 using global::Unity; | 10 using global::Unity; |
11 using Implab.Xml; | |
11 using static Trace<ConfigurationContext>; | 12 using static Trace<ConfigurationContext>; |
12 | 13 |
13 public class ConfigurationContext { | 14 public class ConfigurationContext { |
14 Regex _nsRx = new Regex(@"^\w+(\.\w+)*$", RegexOptions.Compiled); | |
15 readonly LinkedList<string> m_namespases = new LinkedList<string>(); | |
16 | 15 |
17 LinkedListNode<string> m_insertAt; | 16 readonly TypeResolver m_resolver; |
17 | |
18 | |
18 | 19 |
19 readonly UnityContainer m_container; | 20 readonly UnityContainer m_container; |
20 | 21 |
21 public ConfigurationContext(UnityContainer container) { | 22 public ConfigurationContext(UnityContainer container) { |
22 m_container = container ?? new UnityContainer(); | 23 m_container = container ?? new UnityContainer(); |
23 m_insertAt = new LinkedListNode<string>(string.Empty); | 24 m_resolver = new TypeResolver(); |
24 m_namespases.AddFirst(m_insertAt); | |
25 } | 25 } |
26 | 26 |
27 public void AddNamespace(string ns) { | 27 |
28 Safe.ArgumentMatch(ns, nameof(ns), _nsRx); | 28 public Type Resolve(string typeReference) { |
29 if (m_insertAt != null) | 29 return m_resolver.Resolve(TypeReference.Parse(typeReference)); |
30 m_namespases.AddAfter(m_insertAt, ns); | |
31 else | |
32 m_namespases.AddFirst(ns); | |
33 } | 30 } |
34 | 31 |
35 public Type Resolve(TypeReference reference) { | 32 internal void Visit(AbstractRegistration descriptor) { |
36 Safe.ArgumentNotNull(reference, nameof(reference)); | |
37 | |
38 var args = reference.IsGeneric && !reference.IsOpenGeneric ? reference.GenericParameters?.Select(Resolve).ToArray() : null; | |
39 var argc = reference.IsGeneric ? reference.GenericParameters.Length : 0; | |
40 | |
41 foreach (var ns in m_namespases) { | |
42 var typeName = FormatName(new [] { ns, reference.Namespace, reference.TypeName}, argc, args, reference.IsArray); | |
43 | |
44 var resolved = ProbeType(typeName); | |
45 if (resolved != null) { | |
46 Log("Probe succeed {0} in '{1}': {2} -> {3}", reference, ns, typeName, resolved.AssemblyQualifiedName); | |
47 return resolved; | |
48 } else { | |
49 Log("Probe failed {0} in '{1}': {2}", reference, ns, typeName); | |
50 } | |
51 } | |
52 | |
53 throw new Exception($"Failed to resolve: {reference}"); | |
54 } | |
55 | |
56 Type ProbeType(string typeName) { | |
57 var assemblies = AppDomain.CurrentDomain.GetAssemblies(); | |
58 | |
59 foreach(var assembly in assemblies) { | |
60 var type = assembly.GetType(typeName); | |
61 if (type != null) | |
62 return type; | |
63 } | |
64 return null; | |
65 } | |
66 | |
67 string FormatName(string[] parts, int argc, Type[] args, bool isArray) { | |
68 var builder = new StringBuilder(); | |
69 | |
70 builder.Append(String.Join(".", parts.Where(x => !string.IsNullOrEmpty(x)))); | |
71 if (argc > 0) { | |
72 builder.Append('`'); | |
73 builder.Append(argc); | |
74 } | |
75 | |
76 if (args!= null && args.Length > 0) { | |
77 builder.Append('['); | |
78 builder.Append(string.Join(",", args.Select(x => $"[{x.AssemblyQualifiedName}]"))); | |
79 builder.Append(']'); | |
80 } | |
81 | |
82 if(isArray) | |
83 builder.Append("[]"); | |
84 | |
85 return builder.ToString(); | |
86 } | |
87 | |
88 public Type Resolve(string typeReference) { | |
89 return Resolve(TypeReference.Parse(typeReference)); | |
90 } | |
91 | |
92 public void Visist(AbstractRegistration descriptor) { | |
93 | 33 |
94 } | 34 } |
95 | 35 |
36 internal void Visit(NamespaceElement namespaceElement) { | |
37 m_resolver.AddNamespace(namespaceElement.Name); | |
38 } | |
39 | |
40 internal void Visit(AssemblyElement assemblyElement) { | |
41 Assembly.Load(assemblyElement.AssemblyName); | |
42 } | |
43 | |
44 internal void Visit(IncludeElement includeElement) { | |
45 Include(includeElement.Href); | |
46 } | |
47 | |
96 public void Include(string file) { | 48 public void Include(string file) { |
49 var includeContext = new ConfigurationContext(m_container); | |
50 includeContext.LoadConfig(file); | |
51 } | |
97 | 52 |
53 public void LoadConfig(string file) { | |
54 var config = SerializationHelpers.DeserializeFromFile<ContainerElement>(file); | |
55 Visit(config); | |
56 } | |
57 | |
58 public void Visit(ContainerElement containerElement) { | |
59 foreach (var item in containerElement.Items) | |
60 item.Visit(this); | |
98 } | 61 } |
99 | 62 |
100 } | 63 } |
101 } | 64 } |