|
|
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<InjectionMember> m_injections = new List<InjectionMember>();
|
|
|
|
|
|
internal InjectionMember[] Injections { get { return m_injections.ToArray(); } }
|
|
|
|
|
|
public Type ImplementationType {
|
|
|
get;
|
|
|
private set;
|
|
|
}
|
|
|
|
|
|
internal TypeRegistrationBuilder(TypeResolver resolver, Type registrationType, Type implementationType, ContainerBuilder root) : base(registrationType, root) {
|
|
|
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 InjectionParameterBuilder(m_resolver, null, Root);
|
|
|
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 parameters = methodInjection.Parameters?
|
|
|
.Select(x => {
|
|
|
var valueBuilder = new InjectionParameterBuilder(m_resolver, null, Root);
|
|
|
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 = ImplementationType.GetProperty(propertyInjection.Name)?.PropertyType;
|
|
|
var valueContext = new InjectionParameterBuilder(m_resolver, propertyType, Root);
|
|
|
|
|
|
propertyInjection.Value.Visit(valueContext);
|
|
|
var injection = new InjectionProperty(propertyInjection.Name, valueContext.Injection);
|
|
|
m_injections.Add(injection);
|
|
|
}
|
|
|
|
|
|
public void AddInjectionMember(InjectionMember injection) {
|
|
|
Safe.ArgumentNotNull(injection, nameof(injection));
|
|
|
|
|
|
m_injections.Add(injection);
|
|
|
}
|
|
|
}
|
|
|
}
|