我试图了解何时[ImportingConstructor]比使用[import]装饰属性更合适.这是个人偏好,还是允许其他DI容器构建类或者[import]有什么好处的东西?
我想也许如果你不想暴露公共财产,但MEF也会解决私人领域,那么又有什么好处呢?
Jar*_*Par 24
使用的问题[Import]在于它将对象的创建分为两个不同且可观察的阶段:创建和初始化.在哪里[ImportingConstructor]允许它作为单个阶段保持与每个其他.Net对象完全相同.
这种差异在许多方面都可以观察到
[Import]在字段上添加新内容会更改类型的逻辑协定.但它并没有改变公共或使用合同.这意味着以前编译的任何代码都将继续编译,即使对象依赖项已更改(想想单元测试).这需要编译时错误并使其成为运行时错误.[Import].合同验证引擎正确识别所有字段都可以作为null值存在,并且在每次使用字段之前都需要检查. readonly像使用普通的C#对象那样表达它.而不是纯粹根据MEF思考,从更广泛的意义上看你的课堂设计.通常,在设计类时,您有一组关联的属性,这些属性可以是服务,例如,
public class MyService
{
public ILogger Logger { get; set; }
public void SaySomething()
{
Logger.Log("Something");
}
}
Run Code Online (Sandbox Code Playgroud)
现在,我可以继续创建一个实例:
var service = new MyService();
Run Code Online (Sandbox Code Playgroud)
现在,如果我尝试使用该方法:
service.SaySomething();
Run Code Online (Sandbox Code Playgroud)
如果我不明确知道我还必须初始化我的Logger财产:
var service = new MyService() { Logger = new ConsoleLogger() };
Run Code Online (Sandbox Code Playgroud)
(要么):
var service = new MyService();
service.Logger = new ConsoleLogger();
Run Code Online (Sandbox Code Playgroud)
然后错误将在运行时才会变得明显.如果我们要重新定义课程:
public class MyService
{
private readonly ILogger _logger;
public MyService(ILogger logger)
{
if (logger == null) throw new ArgumentNullException("logger");
_logger = logger;
}
public void SaySomething()
{
_logger.Log("Something");
}
}
Run Code Online (Sandbox Code Playgroud)
现在,如果您尝试创建一个实例MyService,则必须ILogger为要正确初始化的对象提供此附加服务().这有助于多种方式:
您可以通过使用代码约定(如@JaredPar所述)在编译时进行静态检查来更好地改进此设计.
就MEF而言,你可以使用[Import]而不是[ImportingConstructor]因为MEF会在它不能满足一个类型的所有导入时抛出异常,并且只会在initialisation([ImportingConstructor])和[Import]s 之后返回类型.
通常优选构造体注射.
通过使用[ImportingConstructor],您允许一个充当导出的类导入其依赖项。这极大地简化了架构,因为您可以将具体对象的依赖关系与其实现解耦。
通常,您会[ImportingConstructor]在本身标记为 的类型上使用[Export]。当类型被组合时,构造函数参数将由 MEF 提供。
| 归档时间: |
|
| 查看次数: |
13261 次 |
| 最近记录: |