.NET实现一个简单的IOC容器
shanzm 人气:0
[TOC]
### 1.主要细节 * 使用反射程序集的方式获取对象的类型 * 通过反射的方式获取指定类型的的所有公共属性 * 通过特性的方式筛选需要注入对象的类型 * 递归的方式为属性注入依赖对象 * **TODO**:循环依赖、生命周期、实例作用域
### 2.具体示例 #### 2.0 依次考虑一下问题 * 首要,用什么存储对象,即什么是对象容器?Dictionary类型做容器 * 其次,怎么获取对象的类型?反射程序集 * 再次,怎么筛选对象类型?使用特性 * 最后,怎么实现属性注入?递归 #### 2.1 实现IOCFac.cs ```cs public class IOCFactory { // IOC容器(创建的对象的容器) // string key:对象类型名 // object value:对象实例 private Dictionary iocDictionaries = new Dictionary();
// IOC中对象类型的容器
// string key:类型名
// Type value:类型
private Dictionary iocTypeDictionaries = new Dictionary();
//加载程序集,将含有我们自定义的特性标签的类的类型存储到类型容器中
public void LoadAssmaly(string asmName)
{
Assembly assembly = Assembly.Load(asmName);
Type[] types = assembly.GetTypes();//注意这里获取的是程序集中的所有定义的类型
// 筛选出含有IOcServiceAttribute特性标签的类,存储其type类型
foreach (Type type in types)
{
IOCServiceAttribute iOCService = type.GetCustomAttribute(typeof(IOCServiceAttribute)) as IOCServiceAttribute;//获取类上的自定义的特性标签
if (iOCService != null)//如果是IOCServiceAttribute标注类,则把其类型存入类型容器中
{
iocTypeDictionaries.Add(type.Name, type);//最终其中的数据:{[Student, MyIOC.ClassLib.Student],[Teacher, MyIOC.ClassLib.Teacher]}
}
}
}
// ioc容器对象创建
public object GetObject(string typeName)
{
//根据参数取出指定的type
Type type = iocTypeDictionaries[typeName];
//创建type类型的对象
object objectValue = Activator.CreateInstance(type);
//获取type类型对象的所有属性
PropertyInfo[] propertyInfos = type.GetProperties();
foreach (PropertyInfo propertyInfo in propertyInfos)
{
//获取类中属性上的自定义IOCInjectAttribute特性标签
IOCInjectAttribute iOCInject = (IOCInjectAttribute)propertyInfo.GetCustomAttribute(typeof(IOCInjectAttribute));
//如果该属性是含有IOCInjectAttribute类型的特性,则为其也创建一个指定的实例(即注入依赖对象)
if (iOCInject != null)
{
//为objectValue的propertyInfo属性赋值
//这里使用了递归的方式创建一个指定类型的实例
propertyInfo.SetValue(objectValue, GetObject(propertyInfo.PropertyType.Name));
}
}
//将创建的对象存储到容器中
iocDictionaries.Add(typeName, objectValue);
return objectValue;
}
}
```
#### 2.2 创建测试类和特性类
新建两个特性类:
```cs
// IOC容器类特性
// 标记了IOCServiceAttribute特性的类,被注册到容器
[AttributeUsage(AttributeTargets.Class)]//表示该自定义的属性只能用于类之上
public class IOCServiceAttribute : Attribute
{
public IOCServiceAttribute()
{
}
}
```
```cs
// IOC依赖注入特性
// 标明IOCInjectAttribute特性的属性,被注入
[AttributeUsage(AttributeTargets.Property)]//表示该自定义的属性只能用于类之上
public class IOCInjectAttribute : Attribute
{
public IOCInjectAttribute()
{
}
}
```
新建两个含有自定义特性的类
```cs
[IOCService]
public class Student
{
[IOCInject]
public Teacher Teacher { set; get; }
public void Study()
{
Teacher.Teach();
Console.WriteLine($"学生:学习中……");
}
}
```
```cs
[IOCService]
public class Teacher
{
//[IOCInject]
//public Student _Student { set; get; }
public void Teach()
{
Console.WriteLine($"老师:教学中……");
}
}
```
#### 2.3 运行测试
```cs
static void Main(string[] args)
{
IOCFactory iOCFactory = new IOCFactory();
iOCFactory.LoadAssmaly("MyIOC");
Student student = (Student)iOCFactory.GetObject("Student");
//student.Teacher = teacher;//不需要在为属性赋值,IOCFactory实现了属性的注入
student.Study();
Console.ReadKey();
}
```
运行结果:
> 老师:教学中……
> 学生:学习中……
### 参考及示例代码下载 * [某公开课]() * [源码下载](https://github.com/shanzm/ASP.NET-MVC/tree/master/011%E6%89%8B%E5%86%99IOC-MyIOC)
shanzm-2020年3月17日 20:06:01
### 1.主要细节 * 使用反射程序集的方式获取对象的类型 * 通过反射的方式获取指定类型的的所有公共属性 * 通过特性的方式筛选需要注入对象的类型 * 递归的方式为属性注入依赖对象 * **TODO**:循环依赖、生命周期、实例作用域
### 2.具体示例 #### 2.0 依次考虑一下问题 * 首要,用什么存储对象,即什么是对象容器?Dictionary类型做容器 * 其次,怎么获取对象的类型?反射程序集 * 再次,怎么筛选对象类型?使用特性 * 最后,怎么实现属性注入?递归 #### 2.1 实现IOCFac.cs ```cs public class IOCFactory { // IOC容器(创建的对象的容器) // string key:对象类型名 // object value:对象实例 private Dictionary
### 参考及示例代码下载 * [某公开课]() * [源码下载](https://github.com/shanzm/ASP.NET-MVC/tree/master/011%E6%89%8B%E5%86%99IOC-MyIOC)
加载全部内容