IOC控制反转DI依赖注入

380 阅读2分钟

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>();
            }