annotate Implab.ServiceHost/Unity/InjectionValueBuilder.cs @ 281:e0916ddc9950 v3 tip

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