|
|
using System;
|
|
|
using System.Reflection;
|
|
|
using Unity;
|
|
|
|
|
|
namespace Implab.ServiceHost.Unity {
|
|
|
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, true);
|
|
|
}
|
|
|
|
|
|
|
|
|
internal void Visit(TypeAbstractRegistration typeRegistration) {
|
|
|
var registrationType = typeRegistration.GetRegistrationType(ResolveType);
|
|
|
var implementationType = typeRegistration.GetImplementationType(ResolveType) ?? registrationType;
|
|
|
|
|
|
var registrationContext = new TypeRegistrationBuilder(
|
|
|
m_resolver,
|
|
|
registrationType,
|
|
|
implementationType
|
|
|
);
|
|
|
|
|
|
typeRegistration.Visit(registrationContext);
|
|
|
|
|
|
m_container.RegisterType(
|
|
|
registrationContext.RegistrationType,
|
|
|
registrationContext.ImplementationType,
|
|
|
typeRegistration.Name,
|
|
|
registrationContext.Lifetime,
|
|
|
registrationContext.Injections
|
|
|
);
|
|
|
}
|
|
|
|
|
|
internal void Visit(InstanceAbstractRegistration instanceRegistration) {
|
|
|
var registrationType = instanceRegistration.GetRegistrationType(ResolveType);
|
|
|
|
|
|
var builder = new InstanceRegistrationBuilder(m_resolver, registrationType);
|
|
|
|
|
|
instanceRegistration.Visit(builder);
|
|
|
|
|
|
m_container.RegisterInstance(
|
|
|
builder.ValueBuilder.ValueType,
|
|
|
instanceRegistration.Name,
|
|
|
builder.ValueBuilder.Value,
|
|
|
builder.Lifetime
|
|
|
);
|
|
|
}
|
|
|
|
|
|
internal void Visit(FactoryAbstractRegistratrion factoryRgistration) {
|
|
|
var registrationType = factoryRgistration.GetRegistrationType(ResolveType);
|
|
|
|
|
|
var builder = new FactoryRegistrationBuilder(registrationType);
|
|
|
|
|
|
factoryRgistration.Visit(builder);
|
|
|
|
|
|
m_container.RegisterType(
|
|
|
builder.RegistrationType,
|
|
|
factoryRgistration.Name,
|
|
|
builder.Lifetime,
|
|
|
builder.Factory
|
|
|
);
|
|
|
}
|
|
|
|
|
|
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.Injection,
|
|
|
builder.Lifetime
|
|
|
);
|
|
|
}
|
|
|
|
|
|
public void Visit(IFactoryRegistration registration) {
|
|
|
Safe.ArgumentNotNull(registration, nameof(registration));
|
|
|
|
|
|
var registrationType = registration.GetRegistrationType(this);
|
|
|
|
|
|
var builder = new FactoryRegistrationBuilder(registrationType);
|
|
|
|
|
|
if (registration.MemberInjections != null) {
|
|
|
foreach(var member in registration.MemberInjections)
|
|
|
member?.Visit(builder);
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
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);
|
|
|
}
|
|
|
|
|
|
}
|
|
|
}
|