using System; using System.Collections.Generic; using System.ComponentModel; using System.Linq; using System.Xml.Serialization; using Unity.Injection; namespace Implab.ServiceHost.Unity { public class InjectionParameterBuilder { readonly TypeResolver m_resolver; public Type DefaultType { get; private set; } public Type ValueType { get; private set; } public object Value { get; set; } internal InjectionParameterValue Injection { get { if (Value != null) return InjectionParameterValue.ToParameter(Value); return new InjectionParameter(ValueType, null); } } internal InjectionParameterBuilder(TypeResolver resolver, Type defaultType) { m_resolver = resolver; DefaultType = defaultType; } public Type ResolveInjectedValueType(string typeSpec) { if (string.IsNullOrEmpty(typeSpec)) { if (DefaultType == null) throw new Exception("The type must be specified"); return DefaultType; } return m_resolver.Resolve(typeSpec, true); } public Type ResolveType(string typeSpec) { return m_resolver.Resolve(typeSpec, true); } public void SetValue(Type type, object value) { ValueType = type; Value = value; } public void SetValue(T value) { SetValue(typeof(T), value); } public void SetDependencyReference(Type type, string name, bool optional) { ValueType = type; Value = optional ? (object)new OptionalParameter(type, name) : new ResolvedParameter(type, name); } internal void Visit(ArrayParameterElement arrayParameter) { Type itemsType = null; var arrayType = string.IsNullOrEmpty(arrayParameter.TypeName) ? null : ResolveType(arrayParameter.TypeName); if (!string.IsNullOrEmpty(arrayParameter.ItemsType)) { itemsType = ResolveType(arrayParameter.ItemsType); if (arrayType == null) arrayType = itemsType.MakeArrayType(); } else { itemsType = arrayType?.GetInterface(typeof(IEnumerable<>).FullName)?.GetGenericArguments()[0]; } if (itemsType == null) throw new Exception("Failed to determine array elements type"); InjectionParameterValue[] injections = (arrayParameter.Items ?? new InjectionParameterElement[0]) .Select(x => { var builder = new InjectionParameterBuilder(m_resolver, itemsType); x.Visit(builder); return builder.Injection; }) .ToArray(); var array = itemsType.IsGenericParameter ? (object)new GenericResolvedArrayParameter(itemsType.Name, injections) : new ResolvedArrayParameter(itemsType, injections); ValueType = arrayType; Value = array; } } }