马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?立即注册
×
目次
1. IoC容器对象项目结构的影响
代码体现:
2. IoC容器中的对象依赖注入
代码体现:
3. IoC概念明白与自界说IoC容器
代码体现:
4. 自界说IoC容器的根本控制逻辑
5. IOC瞬态模式与单例模式逻辑整合
代码体现:
6. 无穷层级的依赖注入逻辑处置惩罚
代码体现:
7. 属性注入逻辑处置惩罚
代码体现:
8. 单接口多实现注入逻辑处置惩罚
代码体现:
9.完备代码
总结
1. IoC容器对象项目结构的影响
IoC容器的作用是将对象的创建和依赖关系的管理从代码中解耦出来,交给容器来处置惩罚。通过这种方式,项目的结构会更加清楚和模块化。
代码体现:
在你的代码中,MyIoc 类是一个自界说的IoC容器。它通过 _instenceDic 字典来管理对象的注册和实例化。这种筹划使得对象的创建和依赖关系不再硬编码在业务逻辑中,而是由容器同一管理。
- 解耦:对象的创建和依赖关系由 MyIoc 管理,业务代码只须要通过 Resolve 方法获取实例,无需关心对象的创建过程。
- 模块化:通过接口和抽象类界说依赖关系,具体的实现类由容器注入,加强了代码的模块化。
2. IoC容器中的对象依赖注入
依赖注入(DI)是IoC的一种实现方式。通过依赖注入,对象的依赖关系由外部容器在运行时注入,而不是在对象内部硬编码。
代码体现:
在 MyIoc 类中,依赖注入重要通过以下方式实现:
- 构造函数注入:在 CreateInstence 方法中,通过反射获取构造函数的参数,并从容器中剖析这些参数,终极创建对象实例。
- 属性注入:在 CreateInstence 方法中,通过反射获取对象的属性,并根据属性的标记(如 DependyAttribute)从容器中剖析并注入依赖。
比方:
- // 构造函数注入
- ConstructorInfo[] cis = _instenceDic[key].ObjectType.GetConstructors();
- ParameterInfo[] cpis = cis[0].GetParameters();
- List<object> objects = new List<object>();
- foreach (ParameterInfo cpi in cpis)
- {
- string paramTypeKey = cpi.ParameterType.FullName;
- if (_instenceDic.ContainsKey(paramTypeKey))
- {
- objects.Add(_instenceDic[paramTypeKey].Instence);
- }
- }
- var obj = Activator.CreateInstance(_instenceDic[key].ObjectType, objects.ToArray());
复制代码
- PropertyInfo[] pis = type.GetProperties();
- foreach (var pi in pis)
- {
- if (pi.IsDefined(typeof(DependyAttribute), false))
- {
- var attr = pi.GetCustomAttribute<DependyAttribute>();
- string paramTypeKey = pi.PropertyType.FullName + (string.IsNullOrEmpty(attr.Token) ? "" : "_#%%$#_" + attr.Token);
- if (_instenceDic.ContainsKey(paramTypeKey))
- {
- pi.SetValue(obj, _instenceDic[paramTypeKey].Instence);
- }
- }
- }
复制代码 3. IoC概念明白与自界说IoC容器
IoC的核心头脑是将对象的创建和依赖关系的管理交给外部容器,而不是在代码中硬编码。通过这种方式,代码的机动性和可维护性得到了提拔。
代码体现:
MyIoc 是一个自界说的IoC容器,它通过字典 _instenceDic 来存储注册的范例和实例。每个注册的范例都包罗一个 InstenceModel 对象,该对象记录了范例的元数据(如是否为单例)以及实例本身。
- 注册范例:通过 Register 和 RegisterSingle 方法将范例注册到容器中。
- 剖析实例:通过 Resolve 方法从容器中获取实例。
4. 自界说IoC容器的根本控制逻辑
MyIoc 类的根本控制逻辑如下:
- Register<T>():注册瞬时对象(每次哀求都创建新实例)。
- RegisterSingle<T>():注册单例对象(整个应用步伐生命周期内只创建一个实例)。
- Register<TFrom, TTo>():注册接口和实现类的关系。
- Resolve<T>():从容器中获取实例。假如注册的范例是单例模式,则返回同一个实例;假如是瞬时模式,则每次返回新的实例。
- 在创建实例时,CreateInstence 方法会递归地剖析构造函数参数和属性依赖,确保全部依赖都被精确注入。
5. IOC瞬态模式与单例模式逻辑整合
在 MyIoc 中,瞬态模式和单例模式的逻辑通过 InstenceModel 中的 IsSinglton 属性举行区分:
- 瞬态模式:每次调用 Resolve 时,都会创建一个新的实例。
- 单例模式:只有在第一次调用 Resolve 时创建实例,后续调用都返回同一个实例。
代码体现:
- if (_instenceDic[key].IsSinglton)
- {
- if (_instenceDic[key].Instence is null)
- {
- lock (_instanceLock)
- {
- if (_instenceDic[key].Instence is null)
- {
- return (T)CreateInstence(key, typeof(T));
- }
- return (T)_instenceDic[key].Instence;
- }
- }
- return (T)_instenceDic[key].Instence;
- }
- else
- {
- // 在瞬时模式下,每次都调用
- return (T)CreateInstence(key, typeof(T));
- }
复制代码 6. 无穷层级的依赖注入逻辑处置惩罚
在 CreateInstence 方法中,通过递归调用 CreateInstence 来处置惩罚无穷层级的依赖注入。当某个对象的构造函数参数或属性依赖其他对象时,容器会递归地剖析这些依赖,直到全部依赖都被满足。
代码体现:
- if (_instenceDic.ContainsKey(paramTypeKey))
- {
- if (_instenceDic[paramTypeKey].IsSinglton)
- {
- if (_instenceDic[paramTypeKey].Instence is null)
- {
- _instenceDic[paramTypeKey].Instence = CreateInstence(paramTypeKey, _instenceDic[paramTypeKey].ObjectType);
- }
- }
- else
- {
- _instenceDic[paramTypeKey].Instence = CreateInstence(paramTypeKey, _instenceDic[paramTypeKey].ObjectType);
- }
- objects.Add(_instenceDic[paramTypeKey].Instence);
- }
复制代码 7. 属性注入逻辑处置惩罚
在 CreateInstence 方法中,通过反射获取对象的属性,并根据属性的标记(如 DependyAttribute)从容器中剖析并注入依赖。
代码体现:
- PropertyInfo[] pis = type.GetProperties();
- foreach (var pi in pis)
- {
- if (pi.IsDefined(typeof(DependyAttribute), false))
- {
- var attr = pi.GetCustomAttribute<DependyAttribute>();
- string paramTypeKey = pi.PropertyType.FullName + (string.IsNullOrEmpty(attr.Token) ? "" : "_#%%$#_" + attr.Token);
- if (_instenceDic.ContainsKey(paramTypeKey))
- {
- pi.SetValue(obj, _instenceDic[paramTypeKey].Instence);
- }
- }
- }
复制代码 8. 单接口多实现注入逻辑处置惩罚
在 MyIoc 中,通过 Register<TFrom, TTo> 和 RegisterSingle<TFrom, TTo> 方法支持单接口多实现的注入。通过 token 参数,可以为同一个接口的差异实现指定差异的标识符,从而在剖析时区分差异的实现。
代码体现:
- public void Register<TFrom, TTo>(string token = "") where TTo : TFrom
- {
- string key = typeof(TFrom).FullName + (String.IsNullOrEmpty(token) ? "" : "_#%%$#_" + token);
- _instenceDic.Add(key, new InstenceModel { ObjectType = typeof(TTo), IsSinglton = false });
- }
复制代码 在剖析时,可以通过指定 token 来获取差异的实现:
- var serviceA = ioc.Resolve<IService>("A");
- var serviceB = ioc.Resolve<IService>("B");
复制代码 9.完备代码
- using System;
- using System.Collections.Generic;
- using System.Reflection;
- namespace MvvmLightLesson.Base
- {
- public class MyIoc
- {
- private static readonly object _instanceLock = new object();
- private static MyIoc instance;
- private Dictionary<string, InstenceModel> _instenceDic = new Dictionary<string, InstenceModel>();
- private MyIoc()
- { }
- public static MyIoc Default
- {
- get
- {
- if (instance == null)
- {
- lock (_instanceLock)
- {
- if (instance == null)
- {
- instance = new MyIoc();
- }
- }
- }
- return instance;
- }
- }
- // 瞬时状态
- public void Register<T>()
- {
- _instenceDic.Add(
- typeof(T).FullName!,
- new InstenceModel { ObjectType = typeof(T), IsSinglton = false });
- }
- public void Register<TFrom, TTo>(string token = "") where TTo : TFrom
- {
- string key =
- typeof(TFrom).FullName +
- (String.IsNullOrEmpty(token) ? "" : "_#%%$#_" + token);
- _instenceDic.Add(
- key,
- new InstenceModel { ObjectType = typeof(TTo), IsSinglton = false });
- }
- // 单例状态
- public void RegisterSingle<T>()
- {
- _instenceDic.Add(
- typeof(T).FullName!,
- new InstenceModel { ObjectType = typeof(T), IsSinglton = true });
- }
- public void RegisterSingle<TFrom, TTo>(string token = "") where TTo : TFrom
- {
- string key =
- typeof(TFrom).FullName +
- (String.IsNullOrEmpty(token) ? "" : "_#%%$#_" + token);
- _instenceDic.Add(
- key,
- new InstenceModel { ObjectType = typeof(TTo), IsSinglton = true });
- }
- public T Resolve<T>()
- {
- string key = typeof(T).FullName;
- if (_instenceDic.ContainsKey(key))
- {
- if (_instenceDic[key].IsSinglton)
- {
- if (_instenceDic[key].Instence is null)
- {
- lock (_instanceLock)
- {
- if (_instenceDic[key].Instence is null)
- {
- // 在单例模式下,之前没有创建实例的前提下调用
- return (T)CreateInstence(key, typeof(T));
- }
- return (T)_instenceDic[key].Instence;
- }
- }
- return (T)_instenceDic[key].Instence;
- }
- else
- {
- // 在瞬时模式下,每次都调用
- return (T)CreateInstence(key, typeof(T));
- }
- }
- return default(T);
- }
- private object CreateInstence(string key, Type type)
- {
- #region 检查构造函数的参数
- // 如果有参数,根据类型动态创建实例
- ConstructorInfo[] cis = _instenceDic[key].ObjectType.GetConstructors();
- ParameterInfo[] cpis = cis[0].GetParameters();
- // 参数列表
- List<object> objects = new List<object>();
- foreach (ParameterInfo cpi in cpis)
- {
- // AAA MySqlDA.
- string paramTypeKey = cpi.ParameterType.FullName;
- if (cpi.IsDefined(typeof(DependyAttribute), false))
- {
- var attr = cpi.GetCustomAttribute<DependyAttribute>();
- paramTypeKey += string.IsNullOrEmpty(attr.Token) ? "" : "_#%%$#_" + attr.Token;
- }
- if (_instenceDic.ContainsKey(paramTypeKey))
- {
- if (_instenceDic[paramTypeKey].IsSinglton)
- {
- if (_instenceDic[paramTypeKey].Instence is null)
- {
- //_instenceDic[paramTypeKey].Instence =
- // Activator.CreateInstance(_instenceDic[paramTypeKey].ObjectType);
- _instenceDic[paramTypeKey].Instence =
- CreateInstence(paramTypeKey, _instenceDic[paramTypeKey].ObjectType);
- }
- }
- else
- {
- _instenceDic[paramTypeKey].Instence =
- CreateInstence(paramTypeKey, _instenceDic[paramTypeKey].ObjectType);
- }
- objects.Add(_instenceDic[paramTypeKey].Instence);
- }
- else
- objects.Add(null);
- }
- #endregion 检查构造函数的参数
- // 创建对象实例,创建之前需要准备好这个对象的构造函数的参数
- var obj = Activator.CreateInstance(_instenceDic[key].ObjectType, objects.ToArray());
- _instenceDic[key].Instence = obj;
- #region 检查属性的注入
- //
- // 哪些属性需要注入 可以通过特性进行区分
- PropertyInfo[] pis = type.GetProperties();
- //type.GetFields();// 获取所有字段
- foreach (var pi in pis)
- {
- // 判断属性上是否有特定标记,如果有,实例化这个属性
- if (pi.IsDefined(typeof(DependyAttribute), false))
- {
- var attr = pi.GetCustomAttribute<DependyAttribute>();
- // 属性注入的时候
- string paramTypeKey = pi.PropertyType.FullName +
- (string.IsNullOrEmpty(attr.Token) ? "" : "_#%%$#_" + attr.Token);
- if (_instenceDic.ContainsKey(paramTypeKey))
- {
- if (_instenceDic[paramTypeKey].IsSinglton)
- {
- if (_instenceDic[paramTypeKey].Instence is null)
- {
- _instenceDic[paramTypeKey].Instence =
- CreateInstence(paramTypeKey, _instenceDic[paramTypeKey].ObjectType);
- }
- }
- else
- {
- _instenceDic[paramTypeKey].Instence =
- CreateInstence(paramTypeKey, _instenceDic[paramTypeKey].ObjectType);
- }
- // 如果已经创建了实例,设置给当前对象的对应属性
- // 第一个参数,指这个值要设置给哪个对象实例的这个属性
- pi.SetValue(obj, _instenceDic[paramTypeKey].Instence);
- }
- }
- }
- #endregion 检查属性的注入
- return obj;
- }
- // 1、对象中的参数未注入
- // 2、多个实现的使用
- // 3、属性注入
- // 4、瞬时注入/单例模式
- }
- internal class InstenceModel
- {
- public object Instence { get; set; }
- public bool IsSinglton { get; set; }
- public Type ObjectType { get; set; }
- }
- }
复制代码 总结
通过 MyIoc 这个自界说IoC容器,我们可以看到IoC容器的核心功能:
- 对象生命周期管理:支持瞬态模式和单例模式。
- 依赖注入:支持构造函数注入和属性注入。
- 机动性:支持单接口多实现的注入。
固然 MyIoc 是一个简单的实现,但它清楚地展示了IoC容器的核心头脑和实现方式。在实际项目中,可以使用更成熟的IoC容器(如Autofac、Unity等)来得到更强大的功能和更好的性能。
|