这个场景跟《手写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(); } }