這個場景跟《手寫Unity容器--極致簡陋版Unity容器》不同,這裡構造AndroidPhone的時候,AndroidPhone依賴於1個IPad 1、IPhone介面 2、AndroidPhone實現 3、IPad介面 4、IPad實現 5、容器--介面 6、容器--實現 7、調用 ...
這個場景跟《手寫Unity容器--極致簡陋版Unity容器》不同,這裡構造AndroidPhone的時候,AndroidPhone依賴於1個IPad
1、IPhone介面
namespace SimplestUnity_OneLayer { interface IPhone { void Call(); } }
2、AndroidPhone實現
namespace SimplestUnity_OneLayer { public class AndroidPhone : IPhone { public AndroidPhone() { Console.WriteLine("{0}構造函數", this.GetType().Name); } } }
3、IPad介面
namespace SimplestUnity_OneLayer { public interface IPad { void Show(); } }
4、IPad實現
namespace SimplestUnity_OneLayer { public class AndroidPad:IPad { public AndroidPad() { Console.WriteLine("{0}構造函數", this.GetType().Name); } public void Show() { Console.WriteLine("看{0}", this.GetType().Name); } } }
5、容器--介面
public interface IDavidContainer { void RegisterType<TFrom, TTo>(); T Resolve<T>(); }
6、容器--實現
namespace SimplestUnity_OneLayer { /// <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]; //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>(); foreach (var para in currentCtor.GetParameters()) { //得到的參數類型是IPad,抽象無法創建實例 var paraType = para.ParameterType; //所以根據IPad Key,得到AndroidPad類型,具體類型就可以創建實例 var targetParaType = containerDictionary[paraType.FullName]; paraList.Add(Activator.CreateInstance(targetParaType)); } return (T)Activator.CreateInstance(type,paraList.ToArray()); } } }
7、調用
namespace SimplestUnity_OneLayer { class Program { static void Main(string[] args) { DaivdContainer davidContainer = new DaivdContainer(); davidContainer.RegisterType<IPhone, AndroidPhone>(); davidContainer.RegisterType<IPad, AndroidPad>(); IPhone iphone = davidContainer.Resolve<IPhone>(); iphone.Call(); } } }