ContainerBuilder.cs
160 lines
| 5.5 KiB
| text/x-csharp
|
CSharpLexer
cin
|
r289 | using System; | |
using System.IO; | |||
using System.Reflection; | |||
using Implab.Diagnostics; | |||
using Unity; | |||
namespace Implab.ServiceHost.Unity { | |||
using Log = Trace<ContainerBuilder>; | |||
public class ContainerBuilder { | |||
readonly TypeResolver m_resolver; | |||
readonly IUnityContainer m_container; | |||
readonly ContainerConfigurationSchema m_schema; | |||
Uri m_location; | |||
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) { | |||
var resolved = string.IsNullOrEmpty(typeReference) ? null : m_resolver.Resolve(typeReference, true); | |||
Log.Debug("ResolveType('{0}'): {1}", typeReference, resolved?.FullName); | |||
return resolved; | |||
} | |||
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, | |||
this | |||
); | |||
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, | |||
this | |||
); | |||
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); | |||
cin
|
r292 | Log.Log($"AddNamespace: {ns}"); | |
cin
|
r289 | } | |
public void AddAssembly(string assembly) { | |||
cin
|
r292 | var asm = Assembly.Load(assembly); | |
Log.Log($"AddAssembly: {assembly} -> {asm.FullName}"); | |||
cin
|
r289 | } | |
/// <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> | |||
public void Include(string file) { | |||
var includeContext = new ContainerBuilder(m_container, m_schema); | |||
if (m_location != null) { | |||
var uri = new Uri(m_location, file); | |||
includeContext.LoadConfig(uri); | |||
} else { | |||
includeContext.LoadConfig(file); | |||
} | |||
} | |||
/// <summary> | |||
/// Resolves a path ralatively to the current container configuration location. | |||
/// </summary> | |||
/// <param name="location">A path yto resolve</param> | |||
/// <returns>Resolved Uri fot the specified location</returns> | |||
public Uri MakeLocationUri(string location) { | |||
return m_location != null ? new Uri(m_location, location) : new Uri(location); | |||
} | |||
/// <summary> | |||
/// Loads a configuration from the specified local file. | |||
/// </summary> | |||
/// <param name="file">The path to the configuration file.</param> | |||
public void LoadConfig(string file) { | |||
Safe.ArgumentNotEmpty(file, nameof(file)); | |||
LoadConfig(new Uri(Path.GetFullPath(file))); | |||
} | |||
public void LoadConfig(Uri location) { | |||
Safe.ArgumentNotNull(location, nameof(location)); | |||
cin
|
r292 | ||
Log.Log($"LoadConfig {location}"); | |||
Safe.ArgumentNotNull(location, nameof(location)); | |||
cin
|
r289 | ||
m_location = location; | |||
var config = m_schema.LoadConfig(location.ToString()); | |||
config.Visit(this); | |||
} | |||
} | |||
} |