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; 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); } } }