Example #1
0
        /// <summary>
        /// 注册
        /// </summary>
        /// <typeparam name="TFrom">接口类型</typeparam>
        /// <typeparam name="TTo">存储类型</typeparam>
        /// <param name="anotherName">别名(用于一个接口多个实现的区分)</param>
        /// <param name="paraArray">常量参数(用于存储构造函数参数有类型string int 等的指)</param>
        /// <param name="lifetimeType">生命周期</param>
        public void Register <TFrom, TTo>(string anotherName             = null, object[] paraArray = null,
                                          EkIocLifetimeType lifetimeType = EkIocLifetimeType.Transient)
            where TTo : TFrom
        {
            //创建注册KEY
            string key = GetKey(typeof(TFrom).FullName, anotherName);
            //创建注册Model
            EkIocContainerRegisterModel rModel = new EkIocContainerRegisterModel()
            {
                TargetType = typeof(TTo),
                Lifetime   = lifetimeType,
            };

            //添加进字典
            mIocContainerDic.Add(key, rModel);
            //如果有常量变量 则把常量变量的值存储
            if (paraArray != null && paraArray.Length > 0)
            {
                mIocParaDic.Add(key, paraArray);
            }
        }
Example #2
0
        private object ResolveObject(Type sourceType, string anotherName = null)
        {
            string key = GetKey(sourceType.FullName, anotherName);     //获取Key
            EkIocContainerRegisterModel model = mIocContainerDic[key]; //获取Model

            #region 根据生命周期获取缓存里面的对象

            switch (model.Lifetime)           //判断生命周期
            {
            case EkIocLifetimeType.Transient: //瞬时  啥也不用干 直接去创建
                break;

            case EkIocLifetimeType.Singleton:     //单例
                if (model.SingleTonInstance == null)
                {
                    break;
                }
                else
                {
                    return(model.SingleTonInstance);
                }

            case EkIocLifetimeType.Scope:     //作用域单例
                if (mIocScopeDic.ContainsKey(key))
                {
                    return(mIocScopeDic[key]);
                }
                break;

            case EkIocLifetimeType.PerThread:     //线程单例
                throw new ArgumentOutOfRangeException("能力有限,线程单例还没有支持!!");

            default:
                throw new ArgumentOutOfRangeException();
            }

            #endregion

            Type type = model.TargetType; //获取类型

            #region 一、 构造函数注入

            //获取所有构造函数
            ConstructorInfo[] ctorInfoArray = type.GetConstructors();
            // 先去查找被特性 EkIocConstructorAttribute 标记的构造函数
            ConstructorInfo ctor = ctorInfoArray
                                   .FirstOrDefault(c => c.IsDefined(typeof(EkIocInjectCtorAttribute), true));
            if (ctor == null)
            {
                //如果没有被特性标记的构造函数
                // 使用构造函数参数类型超集  参数个数最多的
                ctor = ctorInfoArray.OrderBy(c => c.GetParameters().Length).FirstOrDefault();
            }

            //获取并准备构造函数的参数
            List <object> paraList        = new List <object>();
            object[]      paraObjectArray = mIocParaDic.ContainsKey(key) ? mIocParaDic[key] : null; //获取常量参数的值
            int           index           = 0;
            foreach (ParameterInfo para in ctor.GetParameters())
            {
                if (para.IsDefined(typeof(EkIocInjectParameterAttribute), true))
                {
                    if (paraObjectArray != null)
                    {
                        paraList.Add(paraObjectArray[index]);
                    }
                    index++;
                }
                else
                {
                    Type   paraType     = para.ParameterType;             //获取参数的类型
                    string aName        = GetAnotherName(para);           //获取标记的别名
                    object paraInstance = ResolveObject(paraType, aName); //递归获取创建引用的类型
                    paraList.Add(paraInstance);
                }
            }

            #endregion

            //创建对象
            object oInstance = Activator.CreateInstance(type, paraList.ToArray());

            #region 二、 属性注入

            //获取被特性 EkIocInjectPropAttribute 标记的属性
            PropertyInfo[] propInfoArray = type.GetProperties()
                                           .Where(p => p.IsDefined(typeof(EkIocInjectPropAttribute), true)).ToArray();
            foreach (PropertyInfo prop in propInfoArray)
            {
                Type   propType     = prop.PropertyType;              //获取属性的类型
                string aName        = GetAnotherName(prop);           //获取标记的别名
                object propInstance = ResolveObject(propType, aName); //递归获取创建属性引用的类型

                prop.SetValue(oInstance, propInstance);               //把创建的属性类型指定给创建的类型
            }

            #endregion


            #region  、方法注入

            //获取被特性 EkIocInjectMethodAttribute 标记的方法
            MethodInfo[] methodInfoArray = type.GetMethods()
                                           .Where(m => m.IsDefined(typeof(EkIocInjectMethodAttribute), true)).ToArray();
            foreach (MethodInfo method in methodInfoArray)
            {
                List <object> methodParaList = new List <object>();
                foreach (ParameterInfo methodPara in method.GetParameters())
                {
                    Type   paraType     = methodPara.ParameterType;       //获取参数的类型
                    string aName        = GetAnotherName(methodPara);     //获取标记的别名
                    object paraInstance = ResolveObject(paraType, aName); //递归获取创建引用的类型
                    methodParaList.Add(paraInstance);
                }

                method.Invoke(oInstance, methodParaList.ToArray()); //执行方法
            }

            #endregion

            #region 根据生命周期 把对象添加进缓存

            switch (model.Lifetime)           //判断生命周期
            {
            case EkIocLifetimeType.Transient: //瞬时  啥也不用干 直接去创建
                break;

            case EkIocLifetimeType.Singleton:        //单例
                model.SingleTonInstance = oInstance; //存储单例对象
                break;

            case EkIocLifetimeType.Scope:      //作用域单例
                mIocScopeDic[key] = oInstance; //存储在作用域单例字典中
                break;

            case EkIocLifetimeType.PerThread:    //线程单例
                throw new ArgumentOutOfRangeException("能力有限,线程单例还没有支持!!");

            default:
                throw new ArgumentOutOfRangeException();
            }

            #endregion

            return(oInstance);
        }