RegistrationContext.cs
118 lines
| 4.3 KiB
| text/x-csharp
|
CSharpLexer
cin
|
r272 | 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); | |||
} | |||
} | |||
} |