手写 支持无限层级IOC容器,包含构造方法注入,属性注入,方法注入


//注册后服务,存放类型的静态字典 private static Dictionary<string, Type> MapDictionary = new Dictionary<string, Type>();

  

 //注册的本质实际上是将实例与接口 关联起来,在存放到静态字典当中去。
        public void AddTransient<ITServer, TServer>() where TServer:ITServer
        {
            string ITServerFullName = typeof(ITServer).FullName;
            MapDictionary.Add(ITServerFullName, typeof(TServer));
        }

  

public object GetSever(Type type)
        {
            //接口类的全名称
            string fullName = type.FullName;
            //根据接口全名称获取到目标类的类型
            Type TagType = MapDictionary[fullName];
            //因为通过反射生成实例,实际上还是通过的构造参数来实现的。
            //所以这里先提供一个为null的构造参数类型的变量,用来存放我们最终找到的构造函数
            ConstructorInfo constructorInfo = null;
            //根据目标类型获取到所有的构造函数
            ConstructorInfo[] constructorArray = TagType.GetConstructors();
            //先是找到构造函数是否有属性标记,如果有的话,就用有属性标记的构造函数
            List<ConstructorInfo> constructorList = constructorArray.Where(c => c.IsDefined(typeof(MarkConstructorAttribute), true)).ToList();
            //判断是否找到了含有属性标记的构造函数
            if (constructorList != null && constructorList.Count > 0)
            {
                //默认选择第一个有属性标记的构造函数
                constructorInfo = constructorList.First();
            }
            else
            {
                //如果没有找到有属性标记的构造函数, 就找构造函数参数最多的构造函数,通过降序找到第一个构造函数
                constructorInfo=constructorArray.OrderByDescending(c=>c.GetParameters().Count()).First();
            }
            //弄个集合存放找到构造函数所有的参数
            List<object> parameterObject = new List<object>();
            //找到该构造函数的参数,然后循环所有参数
            foreach (var parameter in constructorInfo.GetParameters())
            {
                //然后依次获取到每个参数的类型
                Type parameterType = parameter.ParameterType;
                //递归上述的过程
                object oParameter = GetServer(parameterType);
                //然后在添加到集合当中去
                parameterObject.Add(oParameter);
            }
            //最后创建
            return Activator.CreateInstance(TagType, parameterObject.ToArray());
        
        }

  IOC的本质实际上是一个工厂,IOC就是控制反转,控制反转是一种思想。 目的是解决应用程序设计当中依赖细节的问题,因为如果依赖细节的话,不符合 对外扩展 对内关闭的思想。如果细节改变,势必影响上层依赖的对象

  依赖注入(DI)

  控制反转,依赖注入,依赖倒置原则 三者关系就是:

  以“依赖注入”的方式实现了“控制反转"的效果,以便符合软件工程中“依赖倒置”原则

 

 

下面的内容是支持属性注入的代码,是根据上面的代码变形得来的。

 

 public object GetServer(Type type)
        {
            //接口类的全名称
            string fullName = type.FullName;
            //根据接口全名称获取到目标类的类型
            Type TagType = MapDictionary[fullName];
            //因为通过反射生成实例,实际上还是通过的构造参数来实现的。
            //所以这里先提供一个为null的构造参数类型的变量,用来存放我们最终找到的构造函数
            ConstructorInfo constructorInfo = null;
            //根据目标类型获取到所有的构造函数
            ConstructorInfo[] constructorArray = TagType.GetConstructors();
            //先是找到构造函数是否有属性标记,如果有的话,就用有属性标记的构造函数
            List<ConstructorInfo> constructorList = constructorArray.Where(c => c.IsDefined(typeof(MarkConstructorAttribute), true)).ToList();
            //判断是否找到了含有属性标记的构造函数
            if (constructorList != null && constructorList.Count > 0)
            {
                //默认选择第一个有属性标记的构造函数
                constructorInfo = constructorList.First();
            }
            else
            {
                //如果没有找到有属性标记的构造函数, 就找构造函数参数最多的构造函数,通过降序找到第一个构造函数
                constructorInfo=constructorArray.OrderByDescending(c=>c.GetParameters().Count()).First();
            }
            //弄个集合存放找到构造函数所有的参数
            List<object> parameterObject = new List<object>();
            //找到该构造函数的参数,然后循环所有参数
            foreach (var parameter in constructorInfo.GetParameters())
            {
                //然后依次获取到每个参数的类型
                Type parameterType = parameter.ParameterType;
                //递归上述的过程
                object oParameter = GetServer(parameterType);

                //注意!!这个循环是找的参数对象内的属性
                //遍历该构造函数内的参数对象的所有属性,然后找到属性中有MarkPropertyAttribute 创建后在赋值给参数对象内的属性对象
                foreach (var parameterAttribute in parameterType.GetProperties())
                {
                    if (parameterAttribute.IsDefined(typeof(MarkPropertyAttribute), true))
                    {
                        object oParameterAttributeObject = GetServer(parameterAttribute.PropertyType);
                        parameterAttribute.SetValue(oParameter, oParameterAttributeObject);
                   
                    }
                }

                //然后在添加到集合当中去
                parameterObject.Add(oParameter);
            }

            object tagTypeObject = Activator.CreateInstance(TagType, parameterObject.ToArray());
            //这个循环是找本来的这个对象的属性!!!!
            foreach (var tagTypeAttribute in TagType.GetProperties())
            {
                if (tagTypeAttribute.IsDefined(typeof(MarkPropertyAttribute), true))
                {
                    object tagTypeAttributeObject= GetServer(tagTypeAttribute.PropertyType);
                    tagTypeAttribute.SetValue(tagTypeObject, tagTypeAttributeObject);
                }
            }

            //最后创建
            return tagTypeObject;
        
        }

  

 然后方法注入的方式

 public object GetServer(Type type)
        {
            //接口类的全名称
            string fullName = type.FullName;
            //根据接口全名称获取到目标类的类型
            Type TagType = MapDictionary[fullName];
            //因为通过反射生成实例,实际上还是通过的构造参数来实现的。
            //所以这里先提供一个为null的构造参数类型的变量,用来存放我们最终找到的构造函数
            ConstructorInfo constructorInfo = null;
            //根据目标类型获取到所有的构造函数
            ConstructorInfo[] constructorArray = TagType.GetConstructors();
            //先是找到构造函数是否有属性标记,如果有的话,就用有属性标记的构造函数
            List<ConstructorInfo> constructorList = constructorArray.Where(c => c.IsDefined(typeof(MarkConstructorAttribute), true)).ToList();
            //判断是否找到了含有属性标记的构造函数
            if (constructorList != null && constructorList.Count > 0){
                //默认选择第一个有属性标记的构造函数
                constructorInfo = constructorList.First();
            }
            else{
                //如果没有找到有属性标记的构造函数, 就找构造函数参数最多的构造函数,通过降序找到第一个构造函数
                constructorInfo=constructorArray.OrderByDescending(c=>c.GetParameters().Count()).First();
            }

            #region 构造函数注入
            //弄个集合存放找到构造函数所有的参数
            List<object> parameterObject = new List<object>();
            //找到该构造函数的参数,然后循环所有参数
            foreach (var parameter in constructorInfo.GetParameters())
            {
                //然后依次获取到每个参数的类型
                Type parameterType = parameter.ParameterType;
                //递归上述的过程
                object oParameter = GetServer(parameterType);

                #region 构造函数内的参数属性注入
                //注意!!这个循环是找的参数对象内的属性
                //遍历该构造函数内的参数对象的所有属性,然后找到属性中有MarkPropertyAttribute 创建后在赋值给参数对象内的属性对象
                foreach (var parameterAttribute in parameterType.GetProperties())
                {
                    if (parameterAttribute.IsDefined(typeof(MarkPropertyAttribute), true))
                    {
                        object oParameterAttributeObject = GetServer(parameterAttribute.PropertyType);
                        parameterAttribute.SetValue(oParameter, oParameterAttributeObject);
                   
                    }
                }
                #endregion

                #region 构造函数内的参数方法注入
                //方法注入
                //循环构造参数对象内的所有方法
                foreach (var  oParameterMethod in parameterType.GetMethods())
                {
                    if (oParameterMethod.IsDefined(typeof(MarkMethodAttribute), true))
                    {
                        //object oParameterMethodObject=Get
                        List<object> oParameterMethodParameterList = new List<object>();

                        ParameterInfo[]  oParameterMethodParameterInfo = oParameterMethod.GetParameters();

                        foreach (var methodParameter in oParameterMethodParameterInfo)
                        {
                            object oMethodParmeter = GetServer(methodParameter.ParameterType);
                            oParameterMethodParameterList.Add(oMethodParmeter);
                        }

                        oParameterMethod.Invoke(oParameter, oParameterMethodParameterList.ToArray());
                    }
                }

                #endregion

                //然后在添加到集合当中去
                parameterObject.Add(oParameter);
            }
            #endregion

            object tagTypeObject = Activator.CreateInstance(TagType, parameterObject.ToArray());

            #region 本对象的属性注入
            //这个循环是找本来的这个对象的属性!!!!
            foreach (var tagTypeAttribute in TagType.GetProperties())
            {
                if (tagTypeAttribute.IsDefined(typeof(MarkPropertyAttribute), true))
                {
                    object tagTypeAttributeObject= GetServer(tagTypeAttribute.PropertyType);
                    tagTypeAttribute.SetValue(tagTypeObject, tagTypeAttributeObject);
                }
            }
            #endregion

            #region 本对象的方法注入

            foreach (var tagTypeMethod in TagType.GetMethods())
            {
                if (tagTypeMethod.IsDefined(typeof(MarkMethodAttribute),true))
                {
                    List<object> tagTypeMethodParameterList = new List<object>();
                    ParameterInfo[] tagTypeMethodParameterInfo = tagTypeMethod.GetParameters();
                    foreach (var tagTypeMethodParameter in tagTypeMethodParameterInfo)
                    {
                        object oTagTypeMethodParameterObject = GetServer(tagTypeMethodParameter.ParameterType);
                        tagTypeMethodParameterList.Add(oTagTypeMethodParameterObject);
                    }
                    tagTypeMethod.Invoke(tagTypeObject, tagTypeMethodParameterList.ToArray());
                }
            }
            #endregion
            //最后创建
            return tagTypeObject;
        }

  

  

posted @ 2022-08-01 16:08  法外狂徒派大星  阅读(46)  评论(0)    收藏  举报