Mercurial > pub > ImplabNet
annotate Implab.ServiceHost/Unity/InjectionValueBuilder.cs @ 279:8714471e8d78 v3
Container configuration cleanup, RC2
author | cin |
---|---|
date | Fri, 04 May 2018 18:12:42 +0300 |
parents | 6691aff01de1 |
children | e0916ddc9950 |
rev | line source |
---|---|
274 | 1 using System; |
279 | 2 using System.Collections; |
277 | 3 using System.Collections.Generic; |
274 | 4 using System.ComponentModel; |
277 | 5 using System.Linq; |
274 | 6 using System.Xml.Serialization; |
7 using Unity.Injection; | |
8 | |
9 namespace Implab.ServiceHost.Unity { | |
10 | |
278
6691aff01de1
Implab: added XmlDefaultSeializer (SerializersPool is now obsolete)
cin
parents:
277
diff
changeset
|
11 public class InjectionParameterBuilder { |
274 | 12 |
13 readonly TypeResolver m_resolver; | |
14 | |
15 public Type DefaultType { get; private set; } | |
16 | |
277 | 17 public Type ValueType { get; private set; } |
274 | 18 |
279 | 19 object m_value; |
274 | 20 |
279 | 21 public object Value { |
274 | 22 get { |
279 | 23 if (!ValueSpecified) |
24 throw new InvalidOperationException("The regular value must be set (dependency or array are not situable in this context)"); | |
25 return m_value; | |
26 } | |
27 } | |
28 | |
29 public bool ValueSpecified { get; private set; } | |
30 | |
31 InjectionParameterValue m_injection; | |
274 | 32 |
279 | 33 public InjectionParameterValue Injection { |
34 get { | |
35 if (m_injection == null) | |
36 throw new InvalidOperationException("The injection parameter is not specified"); | |
37 return m_injection; | |
274 | 38 } |
39 } | |
40 | |
279 | 41 public bool InjectionSpecified { |
42 get { return m_injection != null; } | |
43 } | |
44 | |
278
6691aff01de1
Implab: added XmlDefaultSeializer (SerializersPool is now obsolete)
cin
parents:
277
diff
changeset
|
45 internal InjectionParameterBuilder(TypeResolver resolver, Type defaultType) { |
274 | 46 m_resolver = resolver; |
277 | 47 DefaultType = defaultType; |
274 | 48 } |
49 | |
277 | 50 public Type ResolveInjectedValueType(string typeSpec) { |
274 | 51 if (string.IsNullOrEmpty(typeSpec)) { |
52 if (DefaultType == null) | |
53 throw new Exception("The type must be specified"); | |
54 return DefaultType; | |
55 } | |
278
6691aff01de1
Implab: added XmlDefaultSeializer (SerializersPool is now obsolete)
cin
parents:
277
diff
changeset
|
56 return m_resolver.Resolve(typeSpec, true); |
274 | 57 } |
58 | |
277 | 59 public Type ResolveType(string typeSpec) { |
279 | 60 return string.IsNullOrEmpty(typeSpec) ? null : m_resolver.Resolve(typeSpec, true); |
277 | 61 } |
274 | 62 |
277 | 63 public void SetValue(Type type, object value) { |
279 | 64 Safe.ArgumentNotNull(type, nameof(type)); |
65 | |
277 | 66 ValueType = type; |
279 | 67 m_value = value; |
68 ValueSpecified = true; | |
69 | |
70 m_injection = new InjectionParameter(type, value); | |
277 | 71 } |
72 | |
279 | 73 public void SetDependency(Type type, string name, bool optional) { |
74 Safe.ArgumentNotNull(type, nameof(type)); | |
277 | 75 |
76 ValueType = type; | |
279 | 77 ValueSpecified = false; |
78 m_value = null; | |
79 | |
80 m_injection = optional ? (InjectionParameterValue)new OptionalParameter(type, name) : new ResolvedParameter(type, name); | |
274 | 81 } |
82 | |
277 | 83 internal void Visit(ArrayParameterElement arrayParameter) { |
84 Type itemsType = null; | |
85 var arrayType = string.IsNullOrEmpty(arrayParameter.TypeName) ? null : ResolveType(arrayParameter.TypeName); | |
274 | 86 |
279 | 87 if (arrayType == null) |
88 arrayType = DefaultType; | |
89 | |
90 | |
277 | 91 if (!string.IsNullOrEmpty(arrayParameter.ItemsType)) { |
92 itemsType = ResolveType(arrayParameter.ItemsType); | |
279 | 93 arrayType = itemsType.MakeArrayType(); |
277 | 94 } else { |
279 | 95 itemsType = GetItemsType(arrayType); |
277 | 96 } |
274 | 97 |
277 | 98 if (itemsType == null) |
99 throw new Exception("Failed to determine array elements type"); | |
274 | 100 |
277 | 101 InjectionParameterValue[] injections = (arrayParameter.Items ?? new InjectionParameterElement[0]) |
102 .Select(x => { | |
278
6691aff01de1
Implab: added XmlDefaultSeializer (SerializersPool is now obsolete)
cin
parents:
277
diff
changeset
|
103 var builder = new InjectionParameterBuilder(m_resolver, itemsType); |
277 | 104 x.Visit(builder); |
105 return builder.Injection; | |
106 }) | |
107 .ToArray(); | |
108 | |
278
6691aff01de1
Implab: added XmlDefaultSeializer (SerializersPool is now obsolete)
cin
parents:
277
diff
changeset
|
109 var array = itemsType.IsGenericParameter ? |
279 | 110 (InjectionParameterValue)new GenericResolvedArrayParameter(itemsType.Name, injections) : |
278
6691aff01de1
Implab: added XmlDefaultSeializer (SerializersPool is now obsolete)
cin
parents:
277
diff
changeset
|
111 new ResolvedArrayParameter(itemsType, injections); |
6691aff01de1
Implab: added XmlDefaultSeializer (SerializersPool is now obsolete)
cin
parents:
277
diff
changeset
|
112 |
277 | 113 ValueType = arrayType; |
279 | 114 m_value = null; |
115 ValueSpecified = false; | |
116 | |
117 m_injection = array; | |
118 } | |
119 | |
120 Type GetItemsType(Type collectionType) { | |
121 if (collectionType == null) | |
122 return null; | |
123 | |
124 Type itemsType = null; | |
125 | |
126 if (collectionType.GetGenericTypeDefinition() == typeof(IEnumerable<>)) { | |
127 itemsType = collectionType.GetGenericArguments()[0]; | |
128 } else if (collectionType == typeof(IEnumerable)) { | |
129 itemsType = typeof(object); | |
130 } else { | |
131 itemsType = collectionType.GetInterface(typeof(IEnumerable<>).FullName)?.GetGenericArguments()[0]; | |
132 } | |
133 | |
134 return itemsType; | |
274 | 135 } |
136 } | |
137 } |