|
|
using System;
|
|
|
using System.Collections.Generic;
|
|
|
using System.ComponentModel;
|
|
|
using System.Linq;
|
|
|
using System.Xml.Serialization;
|
|
|
using Implab.Xml;
|
|
|
using Unity.Injection;
|
|
|
using Unity.Registration;
|
|
|
|
|
|
namespace Implab.ServiceHost.Unity {
|
|
|
class RegistrationContext {
|
|
|
readonly TypeResolver m_resolver;
|
|
|
|
|
|
List<InjectionMember> m_injections = new List<InjectionMember>();
|
|
|
|
|
|
Type m_defaultType;
|
|
|
|
|
|
public Type RegistrationType {
|
|
|
get;
|
|
|
private set;
|
|
|
}
|
|
|
|
|
|
public Type ImplementationType {
|
|
|
get;
|
|
|
private set;
|
|
|
}
|
|
|
|
|
|
public RegistrationContext(TypeResolver resolver, string typeSpec, string implSpec) {
|
|
|
RegistrationType = resolver.Resolve(string.IsNullOrEmpty(typeSpec) ? implSpec : typeSpec);
|
|
|
|
|
|
|
|
|
ImplementationType = string.IsNullOrEmpty(implSpec) ? RegistrationType : resolver.Resolve(implSpec);
|
|
|
|
|
|
if (RegistrationType.IsGenericTypeDefinition) {
|
|
|
m_resolver = new TypeResolver(resolver);
|
|
|
|
|
|
foreach (var p in ImplementationType.GetGenericArguments())
|
|
|
m_resolver.AddMapping(p.Name, p);
|
|
|
} else {
|
|
|
m_resolver = resolver;
|
|
|
}
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
public InjectionMember[] Injections {
|
|
|
get {
|
|
|
return m_injections.ToArray();
|
|
|
}
|
|
|
}
|
|
|
|
|
|
public void Visit(ConstructorInjectionElement constructorInjection) {
|
|
|
var parameters = constructorInjection.Parameters?.Select(x => x.Resolve(this)).ToArray();
|
|
|
|
|
|
var injection = parameters != null ? new InjectionConstructor(parameters) : new InjectionConstructor();
|
|
|
m_injections.Add(injection);
|
|
|
}
|
|
|
|
|
|
public void Visit(MethodInjectionElement methodInjection) {
|
|
|
var parameters = methodInjection.Parameters?.Select(x => x.Resolve(this)).ToArray();
|
|
|
|
|
|
var injection = parameters != null ? new InjectionMethod(methodInjection.Name, parameters) : new InjectionMethod(methodInjection.Name);
|
|
|
m_injections.Add(injection);
|
|
|
}
|
|
|
|
|
|
public void Visit(PropertyInjectionElement propertyInjection) {
|
|
|
if (propertyInjection.Value == null)
|
|
|
throw new Exception($"A value value must be specified for the property '{propertyInjection.Name}'");
|
|
|
|
|
|
try {
|
|
|
m_defaultType = RegistrationType.GetProperty(propertyInjection.Name)?.PropertyType;
|
|
|
|
|
|
var parameter = propertyInjection.Value.Resolve(this);
|
|
|
var injection = new InjectionProperty(propertyInjection.Name, parameter);
|
|
|
m_injections.Add(injection);
|
|
|
|
|
|
} finally {
|
|
|
m_defaultType = null;
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
Type ResolveParameterType(InjectionParameterElement injectionParameter) {
|
|
|
if (string.IsNullOrEmpty(injectionParameter.TypeName)) {
|
|
|
if (m_defaultType == null)
|
|
|
throw new Exception($"A type must be specified for the parameter {injectionParameter}");
|
|
|
return m_defaultType;
|
|
|
}
|
|
|
return m_resolver.Resolve(injectionParameter.TypeName);
|
|
|
}
|
|
|
|
|
|
public object Resolve(DefaultParameterElement defaultParameter) {
|
|
|
var type = ResolveParameterType(defaultParameter);
|
|
|
|
|
|
return Safe.CreateDefaultValue(type);
|
|
|
}
|
|
|
|
|
|
public object Resolve(ValueParameterElement valueParameter) {
|
|
|
var type = ResolveParameterType(valueParameter);
|
|
|
|
|
|
return TypeDescriptor.GetConverter(type).ConvertFromString(valueParameter.Value);
|
|
|
}
|
|
|
|
|
|
public object Resolve(SerializedParameterElement serializedParameter) {
|
|
|
var type = ResolveParameterType(serializedParameter);
|
|
|
if (serializedParameter.Content == null || serializedParameter.Content.Length == 0)
|
|
|
return Safe.CreateDefaultValue(type);
|
|
|
|
|
|
var serializer = new XmlSerializer(type);
|
|
|
using (var reader = serializedParameter.Content[0].CreateNavigator().ReadSubtree())
|
|
|
return serializer.Deserialize(reader);
|
|
|
}
|
|
|
|
|
|
public InjectionParameterValue Resolve(DependencyParameterElement dependencyParameter) {
|
|
|
var type = ResolveParameterType(dependencyParameter);
|
|
|
return new ResolvedParameter(type, dependencyParameter.DependencyName);
|
|
|
}
|
|
|
}
|
|
|
}
|