comparison 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
comparison
equal deleted inserted replaced
278:6691aff01de1 279:8714471e8d78
1 using System; 1 using System;
2 using System.Collections;
2 using System.Collections.Generic; 3 using System.Collections.Generic;
3 using System.ComponentModel; 4 using System.ComponentModel;
4 using System.Linq; 5 using System.Linq;
5 using System.Xml.Serialization; 6 using System.Xml.Serialization;
6 using Unity.Injection; 7 using Unity.Injection;
13 14
14 public Type DefaultType { get; private set; } 15 public Type DefaultType { get; private set; }
15 16
16 public Type ValueType { get; private set; } 17 public Type ValueType { get; private set; }
17 18
18 public object Value { get; set; } 19 object m_value;
19 20
20 internal InjectionParameterValue Injection { 21 public object Value {
21 get { 22 get {
22 if (Value != null) 23 if (!ValueSpecified)
23 return InjectionParameterValue.ToParameter(Value); 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 }
24 28
25 return new InjectionParameter(ValueType, null); 29 public bool ValueSpecified { get; private set; }
30
31 InjectionParameterValue m_injection;
32
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;
26 } 38 }
39 }
40
41 public bool InjectionSpecified {
42 get { return m_injection != null; }
27 } 43 }
28 44
29 internal InjectionParameterBuilder(TypeResolver resolver, Type defaultType) { 45 internal InjectionParameterBuilder(TypeResolver resolver, Type defaultType) {
30 m_resolver = resolver; 46 m_resolver = resolver;
31 DefaultType = defaultType; 47 DefaultType = defaultType;
39 } 55 }
40 return m_resolver.Resolve(typeSpec, true); 56 return m_resolver.Resolve(typeSpec, true);
41 } 57 }
42 58
43 public Type ResolveType(string typeSpec) { 59 public Type ResolveType(string typeSpec) {
44 return m_resolver.Resolve(typeSpec, true); 60 return string.IsNullOrEmpty(typeSpec) ? null : m_resolver.Resolve(typeSpec, true);
45 } 61 }
46 62
47 public void SetValue(Type type, object value) { 63 public void SetValue(Type type, object value) {
64 Safe.ArgumentNotNull(type, nameof(type));
65
48 ValueType = type; 66 ValueType = type;
49 Value = value; 67 m_value = value;
68 ValueSpecified = true;
69
70 m_injection = new InjectionParameter(type, value);
50 } 71 }
51 72
52 public void SetValue<T>(T value) { 73 public void SetDependency(Type type, string name, bool optional) {
53 SetValue(typeof(T), value); 74 Safe.ArgumentNotNull(type, nameof(type));
54 }
55 75
56 public void SetDependencyReference(Type type, string name, bool optional) {
57 ValueType = type; 76 ValueType = type;
58 Value = optional ? (object)new OptionalParameter(type, name) : new ResolvedParameter(type, name); 77 ValueSpecified = false;
78 m_value = null;
79
80 m_injection = optional ? (InjectionParameterValue)new OptionalParameter(type, name) : new ResolvedParameter(type, name);
59 } 81 }
60 82
61 internal void Visit(ArrayParameterElement arrayParameter) { 83 internal void Visit(ArrayParameterElement arrayParameter) {
62 Type itemsType = null; 84 Type itemsType = null;
63 var arrayType = string.IsNullOrEmpty(arrayParameter.TypeName) ? null : ResolveType(arrayParameter.TypeName); 85 var arrayType = string.IsNullOrEmpty(arrayParameter.TypeName) ? null : ResolveType(arrayParameter.TypeName);
64 86
87 if (arrayType == null)
88 arrayType = DefaultType;
89
90
65 if (!string.IsNullOrEmpty(arrayParameter.ItemsType)) { 91 if (!string.IsNullOrEmpty(arrayParameter.ItemsType)) {
66 itemsType = ResolveType(arrayParameter.ItemsType); 92 itemsType = ResolveType(arrayParameter.ItemsType);
67 if (arrayType == null) 93 arrayType = itemsType.MakeArrayType();
68 arrayType = itemsType.MakeArrayType();
69 } else { 94 } else {
70 itemsType = arrayType?.GetInterface(typeof(IEnumerable<>).FullName)?.GetGenericArguments()[0]; 95 itemsType = GetItemsType(arrayType);
71 } 96 }
72 97
73 if (itemsType == null) 98 if (itemsType == null)
74 throw new Exception("Failed to determine array elements type"); 99 throw new Exception("Failed to determine array elements type");
75 100
80 return builder.Injection; 105 return builder.Injection;
81 }) 106 })
82 .ToArray(); 107 .ToArray();
83 108
84 var array = itemsType.IsGenericParameter ? 109 var array = itemsType.IsGenericParameter ?
85 (object)new GenericResolvedArrayParameter(itemsType.Name, injections) : 110 (InjectionParameterValue)new GenericResolvedArrayParameter(itemsType.Name, injections) :
86 new ResolvedArrayParameter(itemsType, injections); 111 new ResolvedArrayParameter(itemsType, injections);
87 112
88 ValueType = arrayType; 113 ValueType = arrayType;
89 Value = array; 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;
90 } 135 }
91 } 136 }
92 } 137 }