using System; using System.Reflection; using Unity; namespace Implab.ServiceHost.Unity { public class ContainerBuilder { readonly TypeResolver m_resolver; readonly IUnityContainer m_container; readonly ContainerConfigurationSchema m_schema; public IUnityContainer Container { get { return m_container; } } public ContainerBuilder() : this(null, null) { } public ContainerBuilder(IUnityContainer container, ContainerConfigurationSchema schema) { m_container = container ?? new UnityContainer(); m_resolver = new TypeResolver(); m_schema = schema ?? ContainerConfigurationSchema.Default; } public Type ResolveType(string typeReference) { return string.IsNullOrEmpty(typeReference) ? null : m_resolver.Resolve(typeReference, true); } public void Visit(ITypeRegistration registration) { Safe.ArgumentNotNull(registration, nameof(registration)); var registrationType = registration.GetRegistrationType(this); var implementationType = registration.GetImplementationType(this) ?? registrationType; if (registrationType == null) throw new Exception($"A type must be specified for the registration {registration.Name}"); var builder = new TypeRegistrationBuilder( m_resolver, registrationType, implementationType ); builder.Lifetime = registration.GetLifetime(this); if (registration.MemberInjections != null) { foreach(var member in registration.MemberInjections) member.Visit(builder); } m_container.RegisterType( builder.RegistrationType, builder.ImplementationType, registration.Name, builder.Lifetime, builder.Injections ); } public void Visit(IInstanceRegistration registration) { Safe.ArgumentNotNull(registration, nameof(registration)); var registrationType = registration.GetRegistrationType(this); var builder = new InstanceRegistrationBuilder ( m_resolver, registrationType ); builder.Lifetime = registration.GetLifetime(this); if (registration.MemberInjections != null) { foreach(var member in registration.MemberInjections) member.Visit(builder.ValueBuilder); } if (builder.RegistrationType == null && builder.ValueBuilder.ValueType == null) throw new Exception($"A type must be specified for the registration {registration.Name}"); m_container.RegisterInstance( builder.RegistrationType ?? builder.ValueBuilder.ValueType, registration.Name, builder.ValueBuilder.Value, builder.Lifetime ); } public void AddNamespace(string ns) { m_resolver.AddNamespace(ns); } public void AddAssembly(string assembly) { } 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); config.Visit(this); } } }