|  |  | using System; | 
                        
    
    
        |  |  | using System.Collections.Generic; | 
                        
    
    
        |  |  | using System.Text.RegularExpressions; | 
                        
    
    
        |  |  | using Implab.Diagnostics; | 
                        
    
    
        |  |  |  | 
                        
    
    
        |  |  | namespace Implab.ServiceHost.Unity { | 
                        
    
    
        |  |  | using System.Linq; | 
                        
    
    
        |  |  | using System.Reflection; | 
                        
    
    
        |  |  | using System.Text; | 
                        
    
    
        |  |  | using global::Unity; | 
                        
    
    
        |  |  | using global::Unity.Registration; | 
                        
    
    
        |  |  | using Implab.Xml; | 
                        
    
    
        |  |  | using static Trace<ContainerBuilder>; | 
                        
    
    
        |  |  |  | 
                        
    
    
        |  |  | public class ContainerBuilder { | 
                        
    
    
        |  |  |  | 
                        
    
    
        |  |  | readonly TypeResolver m_resolver; | 
                        
    
    
        |  |  |  | 
                        
    
    
        |  |  | readonly UnityContainer m_container; | 
                        
    
    
        |  |  |  | 
                        
    
    
        |  |  | readonly ContainerConfigurationSchema m_schema; | 
                        
    
    
        |  |  |  | 
                        
    
    
        |  |  | public UnityContainer Container { | 
                        
    
    
        |  |  | get { | 
                        
    
    
        |  |  | return m_container; | 
                        
    
    
        |  |  | } | 
                        
    
    
        |  |  | } | 
                        
    
    
        |  |  |  | 
                        
    
    
        |  |  | public ContainerBuilder() : this(null, null) { | 
                        
    
    
        |  |  | } | 
                        
    
    
        |  |  |  | 
                        
    
    
        |  |  | public ContainerBuilder(UnityContainer container, ContainerConfigurationSchema schema) { | 
                        
    
    
        |  |  | m_container = container ?? new UnityContainer(); | 
                        
    
    
        |  |  | m_resolver = new TypeResolver(); | 
                        
    
    
        |  |  | m_schema = schema ?? ContainerConfigurationSchema.Default; | 
                        
    
    
        |  |  | } | 
                        
    
    
        |  |  |  | 
                        
    
    
        |  |  | public Type ResolveType(string typeReference) { | 
                        
    
    
        |  |  | return m_resolver.Resolve(typeReference); | 
                        
    
    
        |  |  | } | 
                        
    
    
        |  |  |  | 
                        
    
    
        |  |  | internal void Visit(RegisterElement registerElement) { | 
                        
    
    
        |  |  | var registrationType = ResolveType(registerElement.RegistrationType); | 
                        
    
    
        |  |  | var implementationType = string.IsNullOrEmpty(registerElement.MapToType) ? registrationType : ResolveType(registerElement.MapToType); | 
                        
    
    
        |  |  |  | 
                        
    
    
        |  |  | var registrationContext = new TypeRegistrationBuilder( | 
                        
    
    
        |  |  | m_resolver, | 
                        
    
    
        |  |  | registrationType, | 
                        
    
    
        |  |  | implementationType | 
                        
    
    
        |  |  | ); | 
                        
    
    
        |  |  |  | 
                        
    
    
        |  |  | if (registerElement.Injectors != null) { | 
                        
    
    
        |  |  | foreach (var injector in registerElement.Injectors) { | 
                        
    
    
        |  |  | injector.Visit(registrationContext); | 
                        
    
    
        |  |  | } | 
                        
    
    
        |  |  | } | 
                        
    
    
        |  |  |  | 
                        
    
    
        |  |  | m_container.RegisterType( | 
                        
    
    
        |  |  | registrationContext.RegistrationType, | 
                        
    
    
        |  |  | registrationContext.ImplementationType, | 
                        
    
    
        |  |  | registerElement.Name, | 
                        
    
    
        |  |  | registerElement.Lifetime?.GetLifetimeManager(this), | 
                        
    
    
        |  |  | registrationContext.Injections | 
                        
    
    
        |  |  | ); | 
                        
    
    
        |  |  | } | 
                        
    
    
        |  |  |  | 
                        
    
    
        |  |  | internal void Visit(SerializedElement serializedElement) { | 
                        
    
    
        |  |  | var registrationType = ResolveType(serializedElement.RegistrationType); | 
                        
    
    
        |  |  | var valueBuilder = new InjectionValueBuilder(m_resolver, null); | 
                        
    
    
        |  |  |  | 
                        
    
    
        |  |  | valueBuilder.Visit(serializedElement); | 
                        
    
    
        |  |  |  | 
                        
    
    
        |  |  | m_container.RegisterInstance( | 
                        
    
    
        |  |  | registrationType, | 
                        
    
    
        |  |  | serializedElement.Name, | 
                        
    
    
        |  |  | valueBuilder.Value, | 
                        
    
    
        |  |  | serializedElement.Lifetime?.GetLifetimeManager(this) | 
                        
    
    
        |  |  | ); | 
                        
    
    
        |  |  | } | 
                        
    
    
        |  |  |  | 
                        
    
    
        |  |  | internal void Visit(ValueElement valueElement) { | 
                        
    
    
        |  |  | var registrationType = ResolveType(valueElement.RegistrationType); | 
                        
    
    
        |  |  | var valueBuilder = new InjectionValueBuilder(m_resolver, null); | 
                        
    
    
        |  |  |  | 
                        
    
    
        |  |  | valueBuilder.Visit(valueElement); | 
                        
    
    
        |  |  |  | 
                        
    
    
        |  |  | m_container.RegisterInstance( | 
                        
    
    
        |  |  | registrationType, | 
                        
    
    
        |  |  | valueElement.Name, | 
                        
    
    
        |  |  | valueBuilder.Value, | 
                        
    
    
        |  |  | valueElement.Lifetime?.GetLifetimeManager(this) | 
                        
    
    
        |  |  | ); | 
                        
    
    
        |  |  | } | 
                        
    
    
        |  |  |  | 
                        
    
    
        |  |  | internal void Visit(NamespaceElement namespaceElement) { | 
                        
    
    
        |  |  | m_resolver.AddNamespace(namespaceElement.Name); | 
                        
    
    
        |  |  | } | 
                        
    
    
        |  |  |  | 
                        
    
    
        |  |  | internal void Visit(AssemblyElement assemblyElement) { | 
                        
    
    
        |  |  | Assembly.Load(assemblyElement.AssemblyName); | 
                        
    
    
        |  |  | } | 
                        
    
    
        |  |  |  | 
                        
    
    
        |  |  | internal void Visit(IncludeElement includeElement) { | 
                        
    
    
        |  |  | Include(includeElement.Href); | 
                        
    
    
        |  |  | } | 
                        
    
    
        |  |  |  | 
                        
    
    
        |  |  | public void Include(string file) { | 
                        
    
    
        |  |  | var includeContext = new ContainerBuilder(m_container, m_schema); | 
                        
    
    
        |  |  | includeContext.LoadConfig(file); | 
                        
    
    
        |  |  | } | 
                        
    
    
        |  |  |  | 
                        
    
    
        |  |  | public void LoadConfig(string file) { | 
                        
    
    
        |  |  | var config = m_schema.LoadFile(file); | 
                        
    
    
        |  |  | Visit(config); | 
                        
    
    
        |  |  | } | 
                        
    
    
        |  |  |  | 
                        
    
    
        |  |  | internal void Visit(ContainerElement containerElement) { | 
                        
    
    
        |  |  | foreach (var item in containerElement.Items) | 
                        
    
    
        |  |  | item.Visit(this); | 
                        
    
    
        |  |  | } | 
                        
    
    
        |  |  |  | 
                        
    
    
        |  |  |  | 
                        
    
    
        |  |  |  | 
                        
    
    
        |  |  | } | 
                        
    
    
        |  |  | } |