comparison Implab.ServiceHost/Unity/InjectionValueBuilder.cs @ 277:963b17c275be v3

Refactoring Added <array> element to injection parameters Working on registrations of factories
author cin
date Sat, 28 Apr 2018 18:48:09 +0300
parents 22629bf26121
children 6691aff01de1
comparison
equal deleted inserted replaced
276:b4e0f81c7425 277:963b17c275be
1 using System; 1 using System;
2 using System.Collections.Generic;
2 using System.ComponentModel; 3 using System.ComponentModel;
4 using System.Linq;
3 using System.Xml.Serialization; 5 using System.Xml.Serialization;
4 using Unity.Injection; 6 using Unity.Injection;
5 7
6 namespace Implab.ServiceHost.Unity { 8 namespace Implab.ServiceHost.Unity {
7 9
9 11
10 readonly TypeResolver m_resolver; 12 readonly TypeResolver m_resolver;
11 13
12 public Type DefaultType { get; private set; } 14 public Type DefaultType { get; private set; }
13 15
14 public Type ValueType { get; set; } 16 public Type ValueType { get; private set; }
15 17
16 public object Value { get; set; } 18 public object Value { get; set; }
17 19
18 public InjectionParameterValue Injection { 20 internal InjectionParameterValue Injection {
19 get { 21 get {
20 if (Value != null) 22 if (Value != null)
21 return InjectionParameterValue.ToParameter(Value); 23 return InjectionParameterValue.ToParameter(Value);
22 24
23 return new InjectionParameter(ValueType, null); 25 return new InjectionParameter(ValueType, null);
24 } 26 }
25 } 27 }
26 28
27 internal InjectionValueBuilder(TypeResolver resolver, Type acceptsType) { 29 internal InjectionValueBuilder(TypeResolver resolver, Type defaultType) {
28 m_resolver = resolver; 30 m_resolver = resolver;
29 DefaultType = acceptsType; 31 DefaultType = defaultType;
30 } 32 }
31 33
32 public Type ResolveType(string typeSpec) { 34 public Type ResolveInjectedValueType(string typeSpec) {
33 if (string.IsNullOrEmpty(typeSpec)) { 35 if (string.IsNullOrEmpty(typeSpec)) {
34 if (DefaultType == null) 36 if (DefaultType == null)
35 throw new Exception("The type must be specified"); 37 throw new Exception("The type must be specified");
36 return DefaultType; 38 return DefaultType;
37 } 39 }
38 return m_resolver.Resolve(typeSpec); 40 return m_resolver.Resolve(typeSpec);
39 } 41 }
40 42
41 public void Visit(ITextValue value) { 43 public Type ResolveType(string typeSpec) {
42 ValueType = ResolveType(value.TypeName); 44 return m_resolver.Resolve(typeSpec);
43
44 Value = string.IsNullOrEmpty(value.Value) ?
45 Safe.CreateDefaultValue(ValueType) :
46 TypeDescriptor.GetConverter(ValueType).ConvertFromString(value.Value);
47 } 45 }
48 46
49 public void Visit(ISerializedValue value) { 47 public void SetValue(Type type, object value) {
50 ValueType = ResolveType(value.TypeName); 48 ValueType = type;
51 49 Value = value;
52 var serializer = new XmlSerializer(ValueType);
53
54 using (var reader = value.GetReader())
55 Value = new InjectionParameter(ValueType, serializer.Deserialize(reader));
56 } 50 }
57 51
58 public void Visit(IDependencyReference value) { 52 public void SetValue<T>(T value) {
59 ValueType = ResolveType(value.TypeName); 53 SetValue(typeof(T), value);
60 Value = new ResolvedParameter(ValueType, value.DependencyName);
61 } 54 }
62 55
56 public void SetDependencyReference(Type type, string name, bool optional) {
57 ValueType = type;
58 Value = optional ? (object)new OptionalParameter(type, name) : new ResolvedParameter(type, name);
59 }
60
61 internal void Visit(ArrayParameterElement arrayParameter) {
62 Type itemsType = null;
63 var arrayType = string.IsNullOrEmpty(arrayParameter.TypeName) ? null : ResolveType(arrayParameter.TypeName);
64
65 if (!string.IsNullOrEmpty(arrayParameter.ItemsType)) {
66 itemsType = ResolveType(arrayParameter.ItemsType);
67 if (arrayType == null)
68 arrayType = itemsType.MakeArrayType();
69 } else {
70 itemsType = arrayType?.GetInterface(typeof(IEnumerable<>).FullName)?.GetGenericArguments()[0];
71 }
72
73 if (itemsType == null)
74 throw new Exception("Failed to determine array elements type");
75
76 InjectionParameterValue[] injections = (arrayParameter.Items ?? new InjectionParameterElement[0])
77 .Select(x => {
78 var builder = new InjectionValueBuilder(m_resolver, itemsType);
79 x.Visit(builder);
80 return builder.Injection;
81 })
82 .ToArray();
83
84 var array = itemsType.IsGenericParameter ? (object)new GenericResolvedArrayParameter(itemsType.Name, injections) : new ResolvedArrayParameter(itemsType, injections);
85 ValueType = arrayType;
86 Value = array;
87 }
63 } 88 }
64 } 89 }