diff 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
line wrap: on
line diff
--- a/Implab.ServiceHost/Unity/InjectionValueBuilder.cs	Sat Apr 28 00:11:38 2018 +0300
+++ b/Implab.ServiceHost/Unity/InjectionValueBuilder.cs	Sat Apr 28 18:48:09 2018 +0300
@@ -1,5 +1,7 @@
 using System;
+using System.Collections.Generic;
 using System.ComponentModel;
+using System.Linq;
 using System.Xml.Serialization;
 using Unity.Injection;
 
@@ -11,11 +13,11 @@
 
         public Type DefaultType { get; private set; }
 
-        public Type ValueType { get; set; }
+        public Type ValueType { get; private set; }
 
         public object Value { get; set; }
 
-        public InjectionParameterValue Injection {
+        internal InjectionParameterValue Injection {
             get {
                 if (Value != null)
                     return InjectionParameterValue.ToParameter(Value);
@@ -24,12 +26,12 @@
             }
         }
 
-        internal InjectionValueBuilder(TypeResolver resolver, Type acceptsType) {
+        internal InjectionValueBuilder(TypeResolver resolver, Type defaultType) {
             m_resolver = resolver;
-            DefaultType = acceptsType;
+            DefaultType = defaultType;
         }
 
-        public Type ResolveType(string typeSpec) {
+        public Type ResolveInjectedValueType(string typeSpec) {
             if (string.IsNullOrEmpty(typeSpec)) {
                 if (DefaultType == null)
                     throw new Exception("The type must be specified");
@@ -38,27 +40,50 @@
             return m_resolver.Resolve(typeSpec);
         }
 
-        public void Visit(ITextValue value) {
-            ValueType = ResolveType(value.TypeName);
+        public Type ResolveType(string typeSpec) {
+            return m_resolver.Resolve(typeSpec);
+        }
 
-            Value = string.IsNullOrEmpty(value.Value) ?
-                Safe.CreateDefaultValue(ValueType) :
-                TypeDescriptor.GetConverter(ValueType).ConvertFromString(value.Value);
+        public void SetValue(Type type, object value) {
+            ValueType = type;
+            Value = value;
+        }
+
+        public void SetValue<T>(T value) {
+            SetValue(typeof(T), value);
+        }
+
+        public void SetDependencyReference(Type type, string name, bool optional) {
+            ValueType = type;
+            Value = optional ? (object)new OptionalParameter(type, name) : new ResolvedParameter(type, name);
         }
 
-        public void Visit(ISerializedValue value) {
-            ValueType = ResolveType(value.TypeName);
+        internal void Visit(ArrayParameterElement arrayParameter) {
+            Type itemsType = null;
+            var arrayType = string.IsNullOrEmpty(arrayParameter.TypeName) ? null : ResolveType(arrayParameter.TypeName);
 
-            var serializer = new XmlSerializer(ValueType);
+            if (!string.IsNullOrEmpty(arrayParameter.ItemsType)) {
+                itemsType = ResolveType(arrayParameter.ItemsType);
+                if (arrayType == null)
+                    arrayType = itemsType.MakeArrayType();
+            } else {
+                itemsType = arrayType?.GetInterface(typeof(IEnumerable<>).FullName)?.GetGenericArguments()[0];
+            }
 
-            using (var reader = value.GetReader())
-                Value = new InjectionParameter(ValueType, serializer.Deserialize(reader));
-        }
+            if (itemsType == null)
+                throw new Exception("Failed to determine array elements type");
 
-        public void Visit(IDependencyReference value) {
-            ValueType = ResolveType(value.TypeName);
-            Value = new ResolvedParameter(ValueType, value.DependencyName);
+            InjectionParameterValue[] injections = (arrayParameter.Items ?? new InjectionParameterElement[0])
+                .Select(x => {
+                    var builder = new InjectionValueBuilder(m_resolver, itemsType);
+                    x.Visit(builder);
+                    return builder.Injection;
+                })
+                .ToArray();
+
+            var array = itemsType.IsGenericParameter ? (object)new GenericResolvedArrayParameter(itemsType.Name, injections) : new ResolvedArrayParameter(itemsType, injections);
+            ValueType = arrayType;
+            Value = array;
         }
-
     }
 }
\ No newline at end of file