ContainerBuilder.cs
142 lines
| 4.6 KiB
| text/x-csharp
|
CSharpLexer
|
|
r274 | using System; | |
|
|
r280 | using System.IO; | |
|
|
r278 | using System.Reflection; | |
|
|
r280 | using Implab.Diagnostics; | |
|
|
r278 | using Unity; | |
|
|
r274 | ||
| namespace Implab.ServiceHost.Unity { | |||
|
|
r280 | using static Trace<ContainerBuilder>; | |
|
|
r274 | public class ContainerBuilder { | |
| readonly TypeResolver m_resolver; | |||
|
|
r279 | readonly IUnityContainer m_container; | |
|
|
r274 | ||
| readonly ContainerConfigurationSchema m_schema; | |||
|
|
r280 | Uri m_location; | |
|
|
r279 | public IUnityContainer Container { | |
|
|
r274 | get { | |
| return m_container; | |||
| } | |||
| } | |||
| public ContainerBuilder() : this(null, null) { | |||
| } | |||
|
|
r279 | public ContainerBuilder(IUnityContainer container, ContainerConfigurationSchema schema) { | |
|
|
r274 | m_container = container ?? new UnityContainer(); | |
| m_resolver = new TypeResolver(); | |||
| m_schema = schema ?? ContainerConfigurationSchema.Default; | |||
| } | |||
| public Type ResolveType(string typeReference) { | |||
|
|
r279 | return string.IsNullOrEmpty(typeReference) ? null : m_resolver.Resolve(typeReference, true); | |
|
|
r274 | } | |
|
|
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 | |||
| ); | |||
|
|
r274 | } | |
|
|
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, | |||
|
|
r279 | builder.ValueBuilder.Value, | |
|
|
r278 | builder.Lifetime | |
| ); | |||
|
|
r274 | } | |
|
|
r278 | public void AddNamespace(string ns) { | |
| m_resolver.AddNamespace(ns); | |||
| } | |||
| public void AddAssembly(string assembly) { | |||
|
|
r274 | } | |
|
|
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> | |||
|
|
r274 | public void Include(string file) { | |
| var includeContext = new ContainerBuilder(m_container, m_schema); | |||
|
|
r280 | ||
| if (m_location != null) { | |||
| var uri = new Uri(m_location, file); | |||
| includeContext.LoadConfig(uri); | |||
| } else { | |||
| includeContext.LoadConfig(file); | |||
| } | |||
|
|
r274 | } | |
|
|
r280 | /// <summary> | |
| /// Loads a configuration from the specified local file. | |||
| /// </summary> | |||
| /// <param name="file">The path to the configuration file.</param> | |||
|
|
r274 | public void LoadConfig(string file) { | |
|
|
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()); | |||
|
|
r277 | config.Visit(this); | |
|
|
r274 | } | |
|
|
r278 | ||
|
|
r274 | } | |
| } |
