diff 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
line wrap: on
line diff
--- a/Implab.ServiceHost/Unity/InjectionValueBuilder.cs	Thu May 03 09:59:44 2018 +0300
+++ b/Implab.ServiceHost/Unity/InjectionValueBuilder.cs	Fri May 04 18:12:42 2018 +0300
@@ -1,4 +1,5 @@
 using System;
+using System.Collections;
 using System.Collections.Generic;
 using System.ComponentModel;
 using System.Linq;
@@ -15,17 +16,32 @@
 
         public Type ValueType { get; private set; }
 
-        public object Value { get; set; }
+        object m_value;
 
-        internal InjectionParameterValue Injection {
+        public object Value {
             get {
-                if (Value != null)
-                    return InjectionParameterValue.ToParameter(Value);
+                if (!ValueSpecified)
+                    throw new InvalidOperationException("The regular value must be set (dependency or array are not situable in this context)");
+                return m_value;
+            }
+        }
+
+        public bool ValueSpecified { get; private set; }
+
+        InjectionParameterValue m_injection;
 
-                return new InjectionParameter(ValueType, null);
+        public InjectionParameterValue Injection {
+            get {
+                if (m_injection == null)
+                    throw new InvalidOperationException("The injection parameter is not specified");
+                return m_injection;
             }
         }
 
+        public bool InjectionSpecified {
+            get { return m_injection != null; }
+        }
+
         internal InjectionParameterBuilder(TypeResolver resolver, Type defaultType) {
             m_resolver = resolver;
             DefaultType = defaultType;
@@ -41,33 +57,42 @@
         }
 
         public Type ResolveType(string typeSpec) {
-            return m_resolver.Resolve(typeSpec, true);
+            return string.IsNullOrEmpty(typeSpec) ? null : m_resolver.Resolve(typeSpec, true);
         }
 
         public void SetValue(Type type, object value) {
+            Safe.ArgumentNotNull(type, nameof(type));
+
             ValueType = type;
-            Value = value;
+            m_value = value;
+            ValueSpecified = true;
+
+            m_injection = new InjectionParameter(type, value);
         }
 
-        public void SetValue<T>(T value) {
-            SetValue(typeof(T), value);
-        }
+        public void SetDependency(Type type, string name, bool optional) {
+            Safe.ArgumentNotNull(type, nameof(type));
 
-        public void SetDependencyReference(Type type, string name, bool optional) {
             ValueType = type;
-            Value = optional ? (object)new OptionalParameter(type, name) : new ResolvedParameter(type, name);
+            ValueSpecified = false;
+            m_value = null;
+            
+            m_injection = optional ? (InjectionParameterValue)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 (arrayType == null)
+                arrayType = DefaultType;
+
+
             if (!string.IsNullOrEmpty(arrayParameter.ItemsType)) {
                 itemsType = ResolveType(arrayParameter.ItemsType);
-                if (arrayType == null)
-                    arrayType = itemsType.MakeArrayType();
+                arrayType = itemsType.MakeArrayType();
             } else {
-                itemsType = arrayType?.GetInterface(typeof(IEnumerable<>).FullName)?.GetGenericArguments()[0];
+                itemsType = GetItemsType(arrayType);
             }
 
             if (itemsType == null)
@@ -82,11 +107,31 @@
                 .ToArray();
 
             var array = itemsType.IsGenericParameter ?
-                (object)new GenericResolvedArrayParameter(itemsType.Name, injections) :
+                (InjectionParameterValue)new GenericResolvedArrayParameter(itemsType.Name, injections) :
                 new ResolvedArrayParameter(itemsType, injections);
 
             ValueType = arrayType;
-            Value = array;
+            m_value = null;
+            ValueSpecified = false;
+            
+            m_injection = array;
+        }
+
+        Type GetItemsType(Type collectionType) {
+            if (collectionType == null)
+                return null;
+
+            Type itemsType = null;
+
+            if (collectionType.GetGenericTypeDefinition() == typeof(IEnumerable<>)) {
+                itemsType = collectionType.GetGenericArguments()[0];
+            } else if (collectionType == typeof(IEnumerable)) {
+                itemsType = typeof(object);
+            } else {
+                itemsType = collectionType.GetInterface(typeof(IEnumerable<>).FullName)?.GetGenericArguments()[0];
+            }
+            
+            return itemsType;
         }
     }
 }
\ No newline at end of file