using System; using System.Collections.Generic; using System.Linq; using Unity.Injection; using Unity.Registration; namespace Implab.ServiceHost.Unity { public class TypeRegistrationBuilder : RegistrationBuilder { readonly TypeResolver m_resolver; readonly List m_injections = new List(); public InjectionMember[] Injections { get { return m_injections.ToArray(); } } public Type ImplementationType { get; private set; } internal TypeRegistrationBuilder(TypeResolver resolver, Type registrationType, Type implementationType) : base(registrationType) { ImplementationType = implementationType; // when registering a generic mapping, register all generic parameter names as local types if (ImplementationType.IsGenericTypeDefinition) { m_resolver = new TypeResolver(resolver); foreach (var p in ImplementationType.GetGenericArguments()) m_resolver.AddMapping(p.Name, p); } else { m_resolver = resolver; } } internal void Visit(ConstructorInjectionElement constructorInjection) { var parameters = constructorInjection.Parameters? .Select(x => { var valueBuilder = new InjectionValueBuilder(m_resolver, null); x.Visit(valueBuilder); return valueBuilder.Injection; }) .ToArray(); var injection = parameters != null ? new InjectionConstructor(parameters) : new InjectionConstructor(); m_injections.Add(injection); } internal void Visit(MethodInjectionElement methodInjection) { var valueContext = new InjectionValueBuilder(m_resolver, null); var parameters = methodInjection.Parameters? .Select(x => { var valueBuilder = new InjectionValueBuilder(m_resolver, null); x.Visit(valueBuilder); return valueBuilder.Injection; }) .ToArray(); var injection = parameters != null ? new InjectionMethod(methodInjection.Name, parameters) : new InjectionMethod(methodInjection.Name); m_injections.Add(injection); } internal void Visit(PropertyInjectionElement propertyInjection) { if (propertyInjection.Value == null) throw new Exception($"A value value must be specified for the property '{propertyInjection.Name}'"); var propertyType = RegistrationType.GetProperty(propertyInjection.Name)?.PropertyType; var valueContext = new InjectionValueBuilder(m_resolver, propertyType); propertyInjection.Value.Visit(valueContext); var injection = new InjectionProperty(propertyInjection.Name, valueContext.Injection); m_injections.Add(injection); } } }