• 3、手写Unity容器--第N层依赖注入


    这个场景跟《手写Unity容器--第一层依赖注入》又不同,这里构造AndroidPhone的时候,AndroidPhone依赖于1个IPad,且依赖于1个IHeadPhone,而HeadPhone又依赖于1个IRootPhone

     

    1、IPhone接口

    namespace SimplestUnity_nLayer
    {
        interface IPhone
        {
            void Call();
        }
    }

    2、AndroidPhone实现

    namespace SimplestUnity_nLayer
    {
        public class AndroidPhone : IPhone
        {
            public AndroidPhone(IPad iPad, IHeadPhone iHeadPhone)
            {
                Console.WriteLine("{0}构造函数", this.GetType().Name);
            }
        }
    }

    3、IPad接口

    namespace SimplestUnity_nLayer
    {
        public interface IPad
        {
            void Show();
        }
    }

    4、IPad实现

    namespace SimplestUnity_nLayer
    {
        public class AndroidPad:IPad
        {
            public AndroidPad()
            {
                Console.WriteLine("{0}构造函数", this.GetType().Name);
            }
    
            public void Show()
            {
                Console.WriteLine("看{0}", this.GetType().Name);
            }
        }
    }

    5、IHeadPhone接口

    namespace SimplestUnity_nLayer
    {
        public interface IHeadPhone
        {
            
        }
    }

    6、IHeadPhone实现

    namespace SimplestUnity_nLayer
    {
        public class HeadPhone : IHeadPhone
        {
            public HeadPhone(IRootPhone iRootPhone)
            {
                Console.WriteLine("Headphone 被构造");
            }
        }
    }

    7、IRootPhone接口

    namespace SimplestUnity_nLayer
    {
        public interface IRootPhone
        {
            
        }
    }

    8、IRootPhone实现

    namespace SimplestUnity_nLayer
    {
        public class RootPhone : IRootPhone
        {
            public RootPhone()
            {
                Console.WriteLine("RootPhone 被构造");
            }
        }
    }

    9、容器--接口

    public interface IDavidContainer
    {
        void RegisterType<TFrom, TTo>();
        
        T Resolve<T>();
    }

    10、容器--实现

    namespace SimplestUnity_nLayer
    {
        /// <summary>
        /// 容器--工厂
        /// </summary>
        public class DaivdContainer:IDaivdContainer
        {
            private Dictionary<string, Type> containerDictionary = new Dictionary<string, Type>();//字典
    
            /// <summary>
            /// 注册类型
            /// </summary>
            /// <typeparam name="TFrom"></typeparam>
            /// <typeparam name="TTo"></typeparam>
            public void RegisterType<TFrom, TTo>()
            {
                containerDictionary.Add(typeof(TFrom).FullName, typeof(TTo));
            }
    
            /// <summary>
            /// 获取实例
            /// </summary>
            /// <typeparam name="T"></typeparam>
            /// <returns></returns>
            public T Resolve<T>()
            {
                Type type = containerDictionary[typeof(T).FullName];
                return (T)this.CreateInstance(type);
            }
    
            private object CreateInstance(Type type)
            {
                //1、得到类型的所有构造函数
                ConstructorInfo[] ctorArray = type.GetConstructors();
    
                //2、只得到有标记DavidInjectionConstructor特性的构造函数,如果都没有标记特性,那么得到参数最多的构造函数
                ConstructorInfo currentCtor = null;
    
                if (ctorArray.Count(c => c.IsDefined(typeof(DavidInjectionConstructor), true)) > 0)
                {
                    currentCtor = ctorArray.FirstOrDefault(c => c.IsDefined(typeof(DavidInjectionConstructor), true));//得到第1个标记DavidInjectionConstructor特性的构造函数
                }
                else
                {
                    currentCtor = ctorArray.OrderByDescending(c => c.GetParameters().Length).FirstOrDefault();//得到参数个数最多的构造函数
                }
                List<object> paraList = new List<object>();
                //递归:隐形的跳出条件,条件就是GetParameters结果为空,targetType拥有无参数构造函数
                foreach (var para in currentCtor.GetParameters())
                {
                    //得到的参数类型是IPad,抽象无法创建实例
                    var paraType = para.ParameterType;
                    //所以根据IPad Key,得到AndroidPad类型,具体类型就可以创建实例
                    var targetParaType = containerDictionary[paraType.FullName];
                    //继续检查targetParaType的构造函数,不能直接创建实例了
                    Object obj = this.CreateInstance(targetParaType);
                    
                    paraList.Add(obj);
                }
                return Activator.CreateInstance(type, paraList.ToArray());
            }
        }
    }

    11、调用

    class Program
    {
        static void Main(string[] args)
        {
            DaivdContainer davidContainer = new DaivdContainer();
            davidContainer.RegisterType<IPhone, AndroidPhone>();
            davidContainer.RegisterType<IPad, AndroidPad>();
            davidContainer.RegisterType<IHeadPhone, HeadPhone>();
            davidContainer.RegisterType<IRootPhone, RootPhone>();
            IPhone iphone = davidContainer.Resolve<IPhone>();
            iphone.Call();
        }
    }

  • 相关阅读:
    理解爬虫原理
    中文词频统计与词云生成
    复合数据类型,英文词频统计
    字符串操作、文件操作,英文词频统计预处理
    了解大数据的特点、来源与数据呈现方式
    为Bootstrap模态对话框添加拖拽移动功能
    前端进阶学习笔记
    前端基础学习笔记
    MySQL学习笔记(模块二)
    MySQL学习笔记(模块一)
  • 原文地址:https://www.cnblogs.com/dearroy/p/12775057.html
Copyright © 2020-2023  润新知