ContainerBuilder.cs
142 lines
| 4.6 KiB
| text/x-csharp
|
CSharpLexer
cin
|
r274 | using System; | |
cin
|
r280 | using System.IO; | |
cin
|
r278 | using System.Reflection; | |
cin
|
r280 | using Implab.Diagnostics; | |
cin
|
r278 | using Unity; | |
cin
|
r274 | ||
namespace Implab.ServiceHost.Unity { | |||
cin
|
r280 | using static Trace<ContainerBuilder>; | |
cin
|
r274 | public class ContainerBuilder { | |
readonly TypeResolver m_resolver; | |||
cin
|
r279 | readonly IUnityContainer m_container; | |
cin
|
r274 | ||
readonly ContainerConfigurationSchema m_schema; | |||
cin
|
r280 | Uri m_location; | |
cin
|
r279 | public IUnityContainer Container { | |
cin
|
r274 | get { | |
return m_container; | |||
} | |||
} | |||
public ContainerBuilder() : this(null, null) { | |||
} | |||
cin
|
r279 | public ContainerBuilder(IUnityContainer container, ContainerConfigurationSchema schema) { | |
cin
|
r274 | m_container = container ?? new UnityContainer(); | |
m_resolver = new TypeResolver(); | |||
m_schema = schema ?? ContainerConfigurationSchema.Default; | |||
} | |||
public Type ResolveType(string typeReference) { | |||
cin
|
r279 | return string.IsNullOrEmpty(typeReference) ? null : m_resolver.Resolve(typeReference, true); | |
cin
|
r274 | } | |
cin
|
r278 | 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 | |||
); | |||
cin
|
r274 | } | |
cin
|
r278 | 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, | |||
cin
|
r279 | builder.ValueBuilder.Value, | |
cin
|
r278 | builder.Lifetime | |
); | |||
cin
|
r274 | } | |
cin
|
r278 | public void AddNamespace(string ns) { | |
m_resolver.AddNamespace(ns); | |||
} | |||
public void AddAssembly(string assembly) { | |||
cin
|
r274 | } | |
cin
|
r280 | /// <summary> | |
/// Includes the confguration. Creates a new <see cref="ContainerBuilder"/>, | |||
/// and loads the configuration to it. The created builder will share the | |||
/// container and will have its own isolated type resolver. | |||
/// </summary> | |||
/// <param name="file">A path to configuration relative to the current configuration.</param> | |||
cin
|
r274 | public void Include(string file) { | |
var includeContext = new ContainerBuilder(m_container, m_schema); | |||
cin
|
r280 | ||
if (m_location != null) { | |||
var uri = new Uri(m_location, file); | |||
includeContext.LoadConfig(uri); | |||
} else { | |||
includeContext.LoadConfig(file); | |||
} | |||
cin
|
r274 | } | |
cin
|
r280 | /// <summary> | |
/// Loads a configuration from the specified local file. | |||
/// </summary> | |||
/// <param name="file">The path to the configuration file.</param> | |||
cin
|
r274 | public void LoadConfig(string file) { | |
cin
|
r280 | Safe.ArgumentNotEmpty(file, nameof(file)); | |
LoadConfig(new Uri(Path.GetFullPath(file))); | |||
} | |||
public void LoadConfig(Uri location) { | |||
Safe.ArgumentNotNull(location, nameof(location)); | |||
m_location = location; | |||
var config = m_schema.LoadConfig(location.ToString()); | |||
cin
|
r277 | config.Visit(this); | |
cin
|
r274 | } | |
cin
|
r278 | ||
cin
|
r274 | } | |
} |