三、手寫Unity容器--第N層依賴注入

這個場景跟《手寫Unity容器--極致簡陋版Unity容器》不一樣,這裏構造AndroidPhone的時候,AndroidPhone依賴於1個IPadiphone

 

一、IPhone接口函數

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

二、AndroidPhone實現this

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

三、IPad接口spa

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

四、IPad實現3d

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

五、IHeadPhone接口code

namespace SimplestUnity_nLayer { public interface IHeadPhone { } }

六、IHeadPhone實現blog

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

七、IRootPhone接口遞歸

namespace SimplestUnity_nLayer { public interface IRootPhone { } }

八、IRootPhone實現接口

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

九、容器--接口ip

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

十、容器--實現

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) { //一、獲得類型的全部構造函數
            ConstructorInfo[] ctorArray = type.GetConstructors(); //二、只獲得有標記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()); } } }

十一、調用

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

相關文章
相關標籤/搜索