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

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

  

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

  

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
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)

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

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

 

 

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

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
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;
        
       }

  

 然后方法注入的方式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
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 @   法外狂徒派大星  阅读(30)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
点击右上角即可分享
微信分享提示