IOC是目标是效果,需要DI依赖注入的手段
一、IOC控制反转
从依赖倒置原则到IOC控制反转实现。从一开始的依赖细节,到依赖抽象,到最后的转到第三方容器,使程序拥有更好的扩展性。
public class Phone
{
public Phone(HeadPhone headPhone)
{
}
}
************************************************
像以往在构造一个类时,需要先实例化依赖的下端对象;
HeadPhone headPhone = new HeadPhone();
Phone phone = new Phone(headPhone);
当有多个类都有引用是会非常麻烦,所以需要依赖注入的手段,会自动去创建实例引用
二、DI依赖注入(离不开抽象)
依赖注入就是能做到构造某个对象时,将依赖的对象自动初始化并注入
1、使用第三方的Unity容器
下载安装nuget包
{//unity容器打法
//构建一个荣耀手机,先需要构建华为,华为需要先构建耳机,耳机需要先构建电池,i开头的是接口
//实例化容器
UnityContainer container = new UnityContainer();
//注册类型<抽象/接口,具体类>
ontainer.RegisterType<IChargerPhone, ChargerPhone>();//充电器
ontainer.RegisterType<IHeadPhone, HeadPhone>();//耳机
ontainer.RegisterType<IPhone, HuaWei>();//华为
//获取实例
ar a = container.Resolve<RongYao>();//荣耀
}
2、手写简单模拟构造函数注入实现
第三方容器
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
namespace QueQueUnityExtend
{
public interface IQueQueUnityContainer
{
void RegisterType<TAbstract, TConcrete>();
T Resolve<T>();
}
public class QueQueUnityContainer:IQueQueUnityContainer
{
Dictionary<string, Type> unityDictionary = new Dictionary<string, Type>();
/// <summary>
/// 注册实例,将实例添加到集合中
/// </summary>
/// <typeparam name="TAbstract"></typeparam>
/// <typeparam name="TConcrete"></typeparam>
public void RegisterType<TAbstract, TConcrete>()
{
unityDictionary.Add(typeof(TAbstract).FullName,typeof(TConcrete));
}
/// <summary>
/// 获取实例
/// </summary>
/// <typeparam name="T"></typeparam>
/// <returns></returns>
public T Resolve<T>()
{
Type type =typeof(T);
return (T)CreateObject(type);
}
/// <summary>
/// 递归创建符合要求的类型
/// </summary>
/// <param name="type"></param>
/// <returns></returns>
public object CreateObject(Type type)
{
//获取构造函数集合
ConstructorInfo[] ConstructorArr = type.GetConstructors();
//实例化一个构造函数
ConstructorInfo constructor = null;
//判断是否有特性,有特效优先,否则是构造函数参数最多的优先
if (ConstructorArr.Count(t=>t.IsDefined(typeof(QueQueUnityAttribute),true))>0)
{
constructor = ConstructorArr.FirstOrDefault(t => t.IsDefined(typeof(QueQueUnityAttribute), true));
}
{
constructor = ConstructorArr.OrderByDescending(t => t.GetParameters().Length).FirstOrDefault();
}
//创建构造函数参数的集合
List<object> list = new List<object>();
foreach (var item in constructor.GetParameters())
{
//获取参数的类型
Type paraType = item.ParameterType;
//从字典中找到具体的类型
Type childType = unityDictionary[paraType.FullName];
//递归创建 递归:隐形的跳出条件,就是GetParameters结果为空,targetType拥有无参数构造函数
var obj = CreateObject(childType);
list.Add(obj);
}
return Activator.CreateInstance(type, list.ToArray());//返回创建的对象
}
}
}
特性
public class QueQueUnityAttribute:Attribute
{
}
实现
{//手打模拟
IQueQueUnityContainer queQueUnity = new QueQueUnityContainer();
queQueUnity.RegisterType<IChargerPhone, ChargerPhone>();
queQueUnity.RegisterType<IHeadPhone, HeadPhone>();
queQueUnity.RegisterType<IPhone, HuaWei>();
var a = queQueUnity.Resolve<RongYao>();
}