14.3 StyletIoC注入
本页详细介绍了构造函数注入和属性注入。
构造函数注入
当 StyletIoC 创建一个类型的新实例时,构造函数注入会自动发生,前提是该类型是使用语法绑定的Bind<...>().To<...>()
,而不是Bind<...>().ToFactory(...)
.
当出现要构造的类型时,StyletIoC 首先需要确定调用哪个构造函数(如果有多个构造函数):
- 如果构造函数用
[Inject]
属性修饰,StyletIoC 将使用它。 - 任何包含 StyletIoC 不知道如何解析且没有默认值的参数类型的构造函数都将被丢弃。
- 选择 StyletIoC 可以提供的参数最多的构造函数,StyletIoC 不能提供值的参数使用默认值。
如果构造函数类型是IEnumerable<T>
some T
,并且您没有明确地将其注册IEnumerable<T>
为 StyletIoC 的服务,但您_确实_注册了一个或多个实现的类型T
,StyletIoC 将构造一个IEnumerable<T>
包含这些类型的实例。
属性注入
构造类型后,StyletIoC 会将值注入所有用该[Inject]
属性修饰的属性和字段。它将注入公共的、受保护的和私有的属性和字段——不建议将值注入私有成员(因为没有反射就不可能设置类型),但你可能需要它。
属性注入的主要问题是你的属性真的应该是世界可写的(因此它可以在没有反射的情况下设置,例如在单元测试中),即使它们不应该从封装的角度来看。这通常以 的属性结束{ set; private get; }
,这真的很糟糕。出于这个原因,构造函数注入几乎总是首选。
因为属性是在构造类型之后注入的,所以构造函数中发生的一切都不能依赖于填充这些属性。这是更喜欢构造函数注入的另一个原因。如果您_确实_需要知道何时注入属性,请实现接口IInjectionAware
。ParametersInjected
注入所有属性后,将调用接口方法。
因为属性注入需要用 装饰属性[Inject]
,所以您的类型不能是 IoC 容器不可知的,因为它们可以使用构造函数注入。如果你想改变 IoC 容器,这会咬你。
IEnumerable<T>
与构造函数注入一样,某些类型的属性T
将注入该类型的集合。
如果 StyletIoC 没有构造类型调用,您也可以执行属性注入IContainer.BuildUp
。例如:
var car = new OldBanger():
ioc.BuildUp(car);
例子:
class OldBanger
{
// 不会被注入 - 没有 [Inject] 属性
public IEngine Engine {
get; set; }
}
class OldBanger
{
// 将被注入,前提是为服务 IEngine 注册了一个类型
[Inject]
public IEngine Engine {
get; set; }
}
class Garage
{
// 将注入为服务 IVehicle 注册的所有类型
[Inject]
public IEnumerable<IVehicle> Vehicles {
get; set; }
}
class OldBanger
{
// 字段也被注入
[Inject]
public IEngine Engine;
}
class OldBanger
{
// This works true, although you really shouldn't do it
[Inject]
private IEngine Engine;
}
class OldBanger : IInjectionAware
{
[Inject]
public IEngine Engine {
get; set; }
public PropertiesInjected()
{
// Do something with this.Engine
}
}
项目原地址:https://github.com/canton7/Stylet
当前文档原地址:https://github.com/canton7/Stylet/wiki/StyletIoC-Injection
上一节:WPF的MVVM框架Stylet开发文档 14.2 StyletIoC 配置
下一节:WPF的MVVM框架Stylet开发文档 14.4 StyletIoC Keys
上一篇:WPF的MVVM框架Stylet开发文档 13.验证模型基类ValidatingModelBase
下一篇:WPF的MVVM框架Stylet开发文档 15. 视图管理器 The ViewManager