控制反转(Inversion of Control,缩写为IoC):是面向对象的设计原则,可以用来减低计算机代码之间的耦合度,通过控制反转,对象在被创建的时候,由一个调控系统内所有对象的外界实体将其所依赖的对象的引用传递给它。也可以说,依赖被注入到对象中。
当然这都是官方的解释,对于刚接触的人可能不太理解,所以我把我的理解分享一下;
这里我把Ioc理解为一个工厂,并且我通过咨询(注册类型)让工厂知道我的业务逻辑,然后工厂知道我的业务逻辑就需要设计出存放货物的箱子(创建容器),等待我取的货物(直接获得实例化)。这样一套流程下来可以清晰的了解不用 new 就可以创建出实例。
这样是不是有点像工厂模式了,当然自己觉得像。
不多说了开始实现(这里实现不适用接口或是抽象类)
首先实现“工厂” 与生产产品的“箱子
public class IocContainer
{
private Dictionary<string, ContentInfo> stock;
//首先创建出存储容器的字典
public IocContainer() => stock = new Dictionary<string, ContentInfo>>();
/// <summary>
/// 我与工厂的沟通让工厂知晓我的业务逻辑key为标记,有了标记工厂才知道那个货物对于那个人
/// </summary>
/// <typeparam name="T1">父类接口</typeparam>
/// <typeparam name="T2">子类</typeparam>
/// <param name="key"></param>
public void Register<T>(string key) where T : class =>
Register<T>(T, new ContentInfo(typeof(T), key, null));
/// <summary>
/// 我与工厂咨询完毕,觉得可以了就与工厂签订协议,工厂开始对我的业务进行分析处理
///并且包方案处理
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="key"></param>
/// <param name="contentInfo"></param>
private void Register<T>(string key, ContentInfo contentInfo)
{
Type type = typeof(T);
//需要知道方案都可以重复利用这里我们可以把方案保存起来
if (!stock.ContainsKey(type))
{
stock.Add(key, contentInfo);
}
}
/// <summary>
/// 现在方案做好了我们需要看一货物的品质,也就是获取类型实例了
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="key"></param>
/// <returns></returns>
public object Resolve(string key)
{
if (!stock.TryGetValue(key, out ContentInfo contentInfo))
{
Debug.Log("键值未注册:" + key);
return null;
}
object obj = contentInfo.obj;
contentInfo.IsInjected = true;
if (contentInfo.IsInjected)
return obj;
}
}
下面开始实现容器
//工厂给我的产品包装的容器
public class ContentInfo
{
//我委托的业务
public Type type { get; private set; }
public string key { get; private set; }
//用来判断是否已经实例了
public bool IsInjected { get; set; }
public object obj { get ;private set; }
//我委托工
private object ins;
public ContentInfo(Type type, string key)
{
this.type = type;
this.key = key;
//使用反射实例出类型
ins = Activator.CreateInstance(type)
}
}
这样就简单的实现了ioc,当然框架使用不是这一套后期我会把框架使用的也发上来方便各位阅读。
//使用
IocContainer container;
private void Start()
{
container=new IocContainer();
container.Register("业务1",类(做业务1的类));
类(做业务1的类) tool=container.Resolve("业务1");
}
IocContainer 可以使用单例,这样只要处理业务的类被注册进去了就不需要要new是不是很方便!
(个人理解,如有问题欢迎指正!!!!!)