ConfigurationContext.cs
100 lines
| 3.3 KiB
| text/x-csharp
|
CSharpLexer
|
|
r268 | using System; | |
| using System.Collections.Generic; | |||
| using System.Text.RegularExpressions; | |||
| using Implab.Diagnostics; | |||
| namespace Implab.ServiceHost.Unity { | |||
| using System.Linq; | |||
|
|
r269 | using System.Reflection; | |
|
|
r268 | using System.Text; | |
|
|
r269 | using global::Unity; | |
|
|
r268 | using static Trace<ConfigurationContext>; | |
| public class ConfigurationContext { | |||
| Regex _nsRx = new Regex(@"^\w+(\.\w+)*$", RegexOptions.Compiled); | |||
| readonly LinkedList<string> m_namespases = new LinkedList<string>(); | |||
| LinkedListNode<string> m_insertAt; | |||
|
|
r269 | readonly UnityContainer m_container; | |
| public ConfigurationContext(UnityContainer container) { | |||
| m_container = container ?? new UnityContainer(); | |||
|
|
r268 | m_insertAt = new LinkedListNode<string>(string.Empty); | |
| m_namespases.AddFirst(m_insertAt); | |||
| } | |||
| public void AddNamespace(string ns) { | |||
| Safe.ArgumentMatch(ns, nameof(ns), _nsRx); | |||
| if (m_insertAt != null) | |||
| m_namespases.AddAfter(m_insertAt, ns); | |||
| else | |||
| m_namespases.AddFirst(ns); | |||
| } | |||
| public Type Resolve(TypeReference reference) { | |||
| Safe.ArgumentNotNull(reference, nameof(reference)); | |||
| var args = reference.IsGeneric && !reference.IsOpenGeneric ? reference.GenericParameters?.Select(Resolve).ToArray() : null; | |||
| var argc = reference.IsGeneric ? reference.GenericParameters.Length : 0; | |||
| foreach (var ns in m_namespases) { | |||
| var typeName = FormatName(new [] { ns, reference.Namespace, reference.TypeName}, argc, args, reference.IsArray); | |||
|
|
r269 | var resolved = ProbeType(typeName); | |
|
|
r268 | if (resolved != null) { | |
|
|
r269 | Log("Probe succeed {0} in '{1}': {2} -> {3}", reference, ns, typeName, resolved.AssemblyQualifiedName); | |
|
|
r268 | return resolved; | |
| } else { | |||
| Log("Probe failed {0} in '{1}': {2}", reference, ns, typeName); | |||
| } | |||
| } | |||
| throw new Exception($"Failed to resolve: {reference}"); | |||
| } | |||
|
|
r269 | Type ProbeType(string typeName) { | |
| var assemblies = AppDomain.CurrentDomain.GetAssemblies(); | |||
| foreach(var assembly in assemblies) { | |||
| var type = assembly.GetType(typeName); | |||
| if (type != null) | |||
| return type; | |||
| } | |||
| return null; | |||
| } | |||
|
|
r268 | string FormatName(string[] parts, int argc, Type[] args, bool isArray) { | |
| var builder = new StringBuilder(); | |||
| builder.Append(String.Join(".", parts.Where(x => !string.IsNullOrEmpty(x)))); | |||
| if (argc > 0) { | |||
| builder.Append('`'); | |||
| builder.Append(argc); | |||
| } | |||
| if (args!= null && args.Length > 0) { | |||
| builder.Append('['); | |||
|
|
r269 | builder.Append(string.Join(",", args.Select(x => $"[{x.AssemblyQualifiedName}]"))); | |
|
|
r268 | builder.Append(']'); | |
| } | |||
| if(isArray) | |||
| builder.Append("[]"); | |||
| return builder.ToString(); | |||
| } | |||
| public Type Resolve(string typeReference) { | |||
| return Resolve(TypeReference.Parse(typeReference)); | |||
| } | |||
|
|
r269 | public void Visist(AbstractRegistration descriptor) { | |
| } | |||
| public void Include(string file) { | |||
|
|
r268 | ||
| } | |||
| } | |||
| } |
