コード例 #1
0
        /// <summary>
        /// 对参数 binding 进行过滤,根据 BindingType 获取实例和注入操作,并返回其结果(有可能是数组)
        /// </summary>
        virtual protected object ResolveBinding(
            IBinding binding,
            Type type,
            InjectionInto member,
            object parentInstance,
            object id)
        {
            #region 构造 InjectionInfo

            var Info = new InjectionInfo()
            {
                member         = member,
                memberType     = type,
                id             = id,
                parentType     = (parentInstance == null ? null : parentInstance.GetType()),
                parentInstance = parentInstance,
                injectType     = binding.type
            };

            #endregion

            #region  过滤 binding 的 condition 条件

            // 如果参数binding的条件不为空(BindingCondition 委托,接受一个 InjectionInfo 参数)
            if (binding.condition != null)
            {
                // 如果所构造的 InjectionInfo 不能通过 condition 委托(返回假)则返回空
                if (!binding.condition(Info))
                {
                    return(null);
                }
            }

            #endregion

            #region 过滤 id 条件

            // 过滤 id 条件(id 和 binding.id 都不能为空且必须相等,但不单独过滤 id 或 binding.id)
            // ,不符合返回空
            bool resolveById  = id != null;
            bool bindingHasId = binding.id != null;
            if ((!resolveById && bindingHasId) ||
                (resolveById && !bindingHasId) ||
                (resolveById && bindingHasId && !binding.id.Equals(id)))
            {
                return(null);
            }

            #endregion

            // 声明实例变量
            object instance = null;

            #region beforeDefaultInstantiate AOT(UnityBinding 由此 AOT 委托方法获取实例)

            // 如果 AOT 委托 BindingEvaluationHandler 不为空就执行
            if (beforeDefaultInstantiate != null)
            {
                var delegates = beforeDefaultInstantiate.GetInvocationList();
                for (int i = 0; i < delegates.Length; i++)
                {
                    instance = ((BindingEvaluationHandler)delegates[i]).Invoke(this, ref binding);
                }
            }

            #endregion

            #region 如果 beforeDefaultInstantiate AOT 没有获取到实例则根据默认方法获取实例

            if (instance == null)
            {
                int length = binding.valueList.Count;

                switch (binding.bindingType)
                {
                // 如果实例类型为 ADDRESS,获取对应的完成注入后的实例
                // 不保存实例化结果到 binding.value
                case BindingType.ADDRESS:
                    if (binding.constraint == ConstraintType.MULTIPLE)
                    {
                        object[] list = new object[length];
                        for (int i = 0; i < length; i++)
                        {
                            list[i] = Instantiate(binding.valueList[i] as Type);
                        }
                        instance = list;
                    }
                    else
                    {
                        instance = Instantiate(binding.value as Type);
                    }
                    break;

                // 如果是工厂类型,将 binding 的值作为工厂类并获取其create方法的结果
                // 可以重写对应的接口类方法来实现所需的生成效果
                case BindingType.FACTORY:
                    instance = (binding.value as IInjectionFactory).Create(Info);
                    break;

                // 如果是单例类型,且 binding 的值是 Type,就实例化该类型并执行注入
                // 同时保存实例化的结果到 binding.value;如果不是 Type 就直接获取其值
                case BindingType.SINGLETON:
                    if (binding.value is Type)
                    {
                        binding.To(Instantiate(binding.value as Type));
                    }

                    instance = binding.value;
                    break;

                // 如果是多例类型,遍历它的所有值,如果值是 Type,就实例化该类型并执行注入
                // 同时保存实例化的结果到当前元素;如果不是 Type 就直接获取其值
                case BindingType.MULTITON:
                    object[] instances = new object[length];
                    for (int i = 0; i < length; i++)
                    {
                        if (binding.valueList[i] is Type)
                        {
                            binding.valueList[i] = Instantiate(binding.value as Type);
                        }
                        instances[i] = binding.valueList[i];
                    }

                    instance = instances;
                    break;
                }
            }

            #endregion

            #region afterInstantiate AOT(EventContainerAOT 由此对获得的实例分类并添加到相应的 list)

            // 如果 AOT 委托 afterInstantiate 不为空执行委托
            if (afterInstantiate != null)
            {
                afterInstantiate(this, ref binding, ref instance);
            }

            #endregion

            // 返回实例
            return(instance);
        }
コード例 #2
0
        /// <summary>
        /// 为指定类型的所有 binding 执行相应的实例化和注入操作,并返回所有新生成的实例
        /// 返回结果可能是 object 或者数组,使用时应加以判断
        /// </summary>
        virtual protected object Resolve(
            Type type,
            InjectionInto member,
            object parentInstance,
            object id)
        {
            object resolution = null;

            #region beforeResolve AOT

            // 如果 AOT Resolve 前置委托不为空就执行
            if (beforeResolve != null)
            {
                var delegates = beforeResolve.GetInvocationList();
                for (int i = 0; i < delegates.Length; i++)
                {
                    var continueExecution = ((TypeResolutionHandler)delegates[i]).Invoke(
                        this,
                        type,
                        member,
                        parentInstance,
                        id,
                        ref resolution);

                    if (!continueExecution)
                    {
                        return(resolution);
                    }
                }
            }

            #endregion

            #region 获取实际类型,并根据实际类型的获取结果从 binder 中获取 binding

            // 存放获取到的 binding 的变量,如果没有指定 id,将获取指定类型的所有 binding;
            // 如果没有指定类型但指定了 id,则获取指定 id 的所有 binding
            IList <IBinding> bindings   = new List <IBinding>();
            Type             inwardType = typeof(object);

            // 不能根据 id 是否为空来过滤,因为 unityBinding 是通过 AOT 来获取实例的,因此即使没有
            // id 也必须进入 ResolveBinding 方法,所以必须先获取其 binding 自身
            // 如果类型为空 id 不为空,根据 id 来获取 binding
            if (type == null)
            {
                bindings = binder.GetIds(id);
            }
            else
            {
                // 判断参数 type 是否为数组是因为实参可能会传入类似 typeof(Type[]) 这样的值
                if (type.IsArray)
                {
                    inwardType = type.GetElementType();
                }
                else
                {
                    inwardType = type;
                }

                if (id != null)
                {
                    bindings.Add(binder.GetBinding(inwardType, id));
                }
                else
                {
                    bindings = binder.GetTypes(inwardType);
                }
            }

            #endregion

            #region 根据从 binder 中获取的 binding 以及 ResolutionMode 的模式获取实例化结果

            IList <object> instances = new List <object>();

            // 如果没有获取到 binding(也就是说无 id 或无匹配),且 ResolutionMode 是 ALWAYS_RESOLVE,
            // 就调用 Instantiate 方法返回参数 type 的执行结果并添加到 instances 中,否则返回空
            if (bindings == null || bindings.Count == 0)
            {
                if (resolutionMode == ResolutionMode.ALWAYS_RESOLVE)
                {
                    instances.Add(Instantiate(type as Type));
                }
                else
                {
                    return(null);
                }
            }
            else
            {
                // 循环调用 ResolveBinding 方法新建实例,并且将新建成功的实例加入到 instances 中去
                for (int i = 0; i < bindings.Count; i++)
                {
                    var instance = ResolveBinding(
                        bindings[i],
                        type,
                        member,
                        parentInstance,
                        id);

                    if (instance is Array)
                    {
                        object[] os     = (object[])instance;
                        int      length = os.Length;

                        for (int n = 0; n < length; n++)
                        {
                            if (os[n] != null)
                            {
                                instances.Add(os[n]);
                            }
                        }
                    }
                    else
                    {
                        if (instance != null)
                        {
                            instances.Add(instance);
                        }
                    }
                }
            }

            #endregion

            #region 整理获取到的实例(组织为单个对象或数组对象)并赋值给 resolution

            // 如果 type 不为空且不是数组、instances的长度为1,将其第0个元素赋值给 resolution
            if (type != null && !type.IsArray && instances.Count == 1)
            {
                resolution = instances[0];
            }
            // 否则就以数组形式赋值给 resolution(将数组存为 object,使用时需要转回数组)
            else if (instances.Count > 0)
            {
                var array = Array.CreateInstance(inwardType, instances.Count);
                for (int i = 0; i < instances.Count; i++)
                {
                    array.SetValue(instances[i], i);
                }
                resolution = array;
            }

            #endregion

            #region afterResolve AOT

            // 如果 AOT Resolve 后置委托不为空就执行
            if (afterResolve != null)
            {
                var delegates = this.afterResolve.GetInvocationList();
                for (int i = 0; i < delegates.Length; i++)
                {
                    var continueExecution = ((TypeResolutionHandler)delegates[i]).Invoke(this,
                                                                                         type,
                                                                                         member,
                                                                                         parentInstance,
                                                                                         id,
                                                                                         ref resolution);

                    if (!continueExecution)
                    {
                        return(resolution);
                    }
                }
            }

            #endregion

            // 返回实例
            return(resolution);
        }