示例#1
0
        internal object Resolve(Type dependency, string name = null)
        {
            Implementation[] impls;
            object           result = null;

            int currThreadId = Thread.CurrentThread.ManagedThreadId;

            if (!recursionControlStackByThreadId
                .TryGetValue(currThreadId, out Stack <Type> atResolvingTypes))
            {
                atResolvingTypes = new Stack <Type>();

                if (!recursionControlStackByThreadId.TryAdd(currThreadId, atResolvingTypes))
                {
                    throw new ApplicationException();
                }
            }
            else
            {
                //check recursion dependency
                if (atResolvingTypes.Contains(dependency))
                {
                    //try create it by constroctor
                    result = CreateByConstructor(dependency);
                    if (result != null)
                    {
                        return(result);
                    }

                    throw new ArgumentException("Depedencies are recursive.");
                }
            }
            atResolvingTypes.Push(dependency);

            if (dependency.IsPrimitive ||
                !dependency.IsClass && !dependency.IsInterface)   //isenum, isStruct
            {
                result = Activator.CreateInstance(dependency);
            }
            else
            if (typeof(IEnumerable).IsAssignableFrom(dependency))
            {
                Type dependencyType = dependency.GetGenericArguments()[0];
                impls = Configuration.GetImplementations(dependencyType).ToArray();

                //create array of Ts (when dependency is IEnumerable<T>)
                var implInstances = (object[])Activator.CreateInstance(dependencyType.MakeArrayType(), new object[] { impls.Count() });
                for (int i = 0; i < impls.Count(); i++)
                {
                    implInstances[i] = impls[i].ResolveOrReturnSingletonInstance(this, name);
                }
                result = implInstances;
            }
            else
            {
                impls = Configuration.GetImplementations(dependency)?.ToArray();
                if (impls == null && dependency.IsGenericType)//handle search for open generic types impls as well
                {
                    impls = Configuration.GetImplementations(dependency.GetGenericTypeDefinition())?.ToArray();
                }
                if (impls != null)
                {
                    Implementation implToUse = impls.First();
                    if (name != null)
                    {
                        implToUse = Array.Find(impls, impl => impl.Name == name);
                    }

                    result = implToUse?.ResolveOrReturnSingletonInstance(this, name); //TODO: resolve dependency on GenericType of impl of open generic dependency
                }
                else //no implementation for that dependency, try make its instance
                {
                    result = CreateByConstructor(dependency);
                }
            }

            atResolvingTypes.Pop();
            return(result);
        }