Mini 容器学习笔记7——构造函数注入
组件工厂在创建组件时将通过一定的策略选定特定的构造函数,然后进行构造。
构造函数的选择策略是:
1. 如果遍历的构造函数如果含有参数,那么容器先检查创建上下文中是否含有指定的参数数组或命名参数字典,如果有则选择该构造函数,反之则遍历构造函数的参数,判断每一个参数是否可以进行注入,如果都可以进行注入则选择该构造函数
2. 如果构造函数没有参数则选择该构造函数
3. 将上面的两个步骤生成的构造函数列表进行按照构造函数参数的个数进行降序排列(构造函数的选择原则是参数越多将被首先选择)
4. 在步骤3的列表 中找出贴有InjectAttribute标签的构造函数,如果找到则选择该构造函数,如果找不到则选择步骤3列表中的第一个构造函数。
构造函数的参数检测策略是:
1. 参数是否贴有标签InjectAttribute和InjectManyAttribute,如果有则根据标签的约束条件检查该参数是否被DI容器注册过,如果注册过,则该参数符合条件,反之不符合条件
2. 如果参数没有标签InjectAttribute和InjectManyAttribute,则根据参数的类型检查是否被DI容器注册过,如果注册过,则该参数符合条件,反之不符合条件
下面通过实例进行学习:
1. 一个简单例子,不带标签的例子
[Contract] interface IHorse { } [Component] class RedHorse : IHorse { } class BlackHorse : IHorse { } class Person2 : IPerson { public string Name { get; set; } public IHorse Horse { get; set; } public Person2(IHorse horse) { Horse = horse; } public Person2() { } } [Test] public void ConstructorInjectTest() { ServiceRegistry .Register<Person2>() .Register<RedHorse>(); var person = ServiceLocator.Get<Person2>(); Assert.IsTrue(person != null); Assert.IsNotNull(person.Horse); }
2. 含有标签的构造函数例子:
class Person5 : IPerson { public string Name { get; set; } public IHorse Horse { get; private set; } public A A {get;private set;} public bool HasVisited { get; private set; } [Inject] public Person5(IHorse horse,A a) { Horse = horse; A = a; HasVisited = true; } [Inject] public Person5(IHorse horse) { Horse = horse; } public Person5() { } } [Test] public void ConstructorInject2Test() { ServiceRegistry.Current.Register("person", typeof(IPerson), typeof(Person5)) .Register("horse", typeof(IHorse), typeof(RedHorse)) .Register("A", typeof(A), typeof(A)) .RegisterInstance("str", typeof(string), "ZhangSan"); var person = ServiceLocator.Get("person") as Person5; Assert.IsTrue(person != null); Assert.IsNotNull(person.Horse); Assert.IsNotNull(person.A); Assert.IsTrue(person.HasVisited); Assert.IsTrue(string.IsNullOrEmpty(person.Name)); }
Mini 容器官方网站:
推荐资源: