Example #1
0
        bool InnerMapCtor(Type actualType, Type expectedType, bool singletonMode
                                          , ConstructorInfo ctor, ParameterInfo[] ps
                                          , out InstanceBox typeInstance
                                          , out Exception exception)
        {
            bool hasExpectedType = expectedType != null;

            if(!singletonMode
                && (actualType.IsDefined(SingletonMappingAttribute.Type, true) || (hasExpectedType && expectedType.IsDefined(SingletonMappingAttribute.Type, true))))
                singletonMode = true;

            InstanceCreatorCallback callback = null;
            if(ps.Length == 0) callback = lastMappingValues => this.WrappingObject(Activator.CreateInstance(actualType, true));
            else
            {
                var psValues = new InstanceBox[ps.Length];
                for(int i = 0; i < ps.Length; i++)
                {
                    var p = ps[i];
                    var pType = p.ParameterType;
                    var pName = p.Name;
                    InstanceBox p_instance = null;
                    if(p.IsDefined(LastMappingAttribute.Type, true)
                        || (pType.IsDefined(LastMappingAttribute.Type, true) && !p.IsDefined(IgnoreAttribute.Type, true)))
                    {
                        p_instance = new InstanceBox(pName, null, pType);
                    }

                    #region 从当前容器获取

                    else if(this.MapContains(actualType, pName)) p_instance = this.FindInstanceBox(actualType, pName);
                    else if(hasExpectedType && this.MapContains(expectedType, pName)) p_instance = this.FindInstanceBox(expectedType, pName);

                    else if(this.MapContains(pName)) p_instance = this.FindInstanceBox(pName);

                    else if(this.MapContains(actualType)) p_instance = this.FindInstanceBox(actualType);
                    else if(hasExpectedType && this.MapContains(expectedType)) p_instance = this.FindInstanceBox(expectedType);

                    #endregion

                    #region 从父级容器获取

                    else if(this._hasParent && this._parentLocator.ContainsValue(actualType, pName, true)) p_instance = new InstanceBox(pName, lmp => this._parentLocator.GetValue(actualType, pName));
                    else if(this._hasParent && hasExpectedType && this._parentLocator.ContainsValue(expectedType, pName, true)) p_instance = new InstanceBox(pName, lmp => this._parentLocator.GetValue(expectedType, pName));

                    else if(this._hasParent && this._parentLocator.ContainsValue(pName, true)) p_instance = new InstanceBox(pName, lmp => this._parentLocator.GetValue(pName));
                    else if(this._hasParent && this._parentLocator.ContainsService(actualType, true)) p_instance = new InstanceBox(pName, lmp => this._parentLocator.GetService(actualType));
                    else if(this._hasParent && hasExpectedType && this._parentLocator.ContainsService(expectedType, true)) p_instance = new InstanceBox(pName, lmp => this._parentLocator.GetService(expectedType));

                    #endregion

                    else if(!pType.IsSimpleType())
                    {
                        //- 从映射事件获取 -or- 尝试智能解析
                        p_instance = this.OnMapResolve(pType) ?? this.AutoResolveExpectType(pType);
                    }

                    if(p_instance == null)
                    {
                        exception = new ArgumentException(actualType.FullName + ":构造函数的参数“" + pName + "”尚未配置映射!", pName);
                        typeInstance = null;
                        return false;
                    }
                    psValues[i] = p_instance;
                }
        
                var cotrHandler = ctor.CreateConstructorHandler();
                callback = lastMappingValues =>
                {
                    System.Collections.IEnumerator cpe = null;
                    Func<bool> moveNextLastMap = () =>
                    {
                        if(cpe == null)
                        {
                            if(lastMappingValues == null) return false;
                            cpe = lastMappingValues.GetEnumerator();
                        }
                        return cpe.MoveNext();
                    };

                    object[] values = new object[psValues.Length];
                    for(int i = 0; i < psValues.Length; i++)
                    {
                        var instanceBox = psValues[i];
                        if(instanceBox.LastMappingType != null)
                        {
                            if(moveNextLastMap())
                            {
                                values[i] = cpe.Current;
                                continue;
                            }
                            var lastMappingBox = OnLastMappingResolve(instanceBox.LastMappingType);
                            if(lastMappingBox == null) throw new ArgumentException(actualType.FullName + ":构造函数的参数“" + instanceBox.Name + "”指定了后期映射关系,但调用方却没有传递映射值!", instanceBox.Name);
                            instanceBox = lastMappingBox;
                        }

                        values[i] = instanceBox.GetInstance();
                    }
                    return WrappingObject(cotrHandler(values));
                };
            }
            typeInstance = singletonMode ? new SingletonInstanceBox(actualType.FullName, callback) : new InstanceBox(actualType.FullName, callback);
            this.Map(expectedType ?? actualType, typeInstance);
            exception = null;
            return true;

        }