我总是尝试以模块化的方式设计我的应用程序。我希望能够在任何给定的交换模块。
使用依赖注入模式使我可以做到这一点。但是有一件事一直困扰着我。
在我遇到的大多数代码中,只有一个地方将接口链接到所需的接口。例如,在asp.net vnext中,它看起来像这样:
public void ConfigureServices(IServiceCollection services)
{
// business-layer
services.AddTransient<IArticleRepository, ArticleRepository>();
// data-layer
services.AddTransient<IDataConnection, DataConnection>();
}但我不喜欢只有一个地方注册。我宁愿让每个模块注册自己的接口/实现:
在我的业务层(模块)中
public void ConfigureServices(IServiceCollection services)
{
// business-layer
services.AddTransient<IArticleRepository, ArticleRepository>();
}在我的数据层(模块)中
public void ConfigureServices(IServiceCollection services)
{
// data-layer
services.AddTransient<IDataConnection, DataConnection>();
}有没有做这类事情的模式或最佳实践?我可以创建一些接口并在加载时遍历该接口的所有实现,但我不确定这是否是最好的方法。
发布于 2015-11-07 22:16:21
有没有做这类事情的模式或最佳实践?
是也不是。在Facade pattern中,您可以向不需要对您的API进行细粒度控制的客户端提供一个简化的API。外观模式本身并不显式地关注依赖注入,但是如果这是一件有意义的事情,那么您可以始终提供默认的服务组合。在我的文章DI Friendly Library中有更多的细节。
也就是说,保持API的开放性很重要,这样Facade就只是您提供给客户端的选项之一。如果您在库中预先编写了一个对象图,且没有为客户端提供任何方法来规避默认组合,那么这样一个库将是一个整体的黑盒。依赖注入带来的所有外部好处都将消失,因为客户端将无法替换或扩展服务。
一定要遵循DI Friendly Library文章中概述的指导原则,但一定要避免使用Conforming Container anti-pattern。
发布于 2015-11-10 05:58:21
我要说的是,配置DI的方式/位置在很大程度上取决于您的DI框架。一些框架允许您进行每个模块的配置,而其他框架则需要一个全局配置。在后一种情况下,您可以手动委派给子模块(只需将IServiceCollection传递给子模块配置代码)。
关于最佳实践:我很少看到DI有多个生产实现的用法。通常只有一个生产实现,DI只是用来将所有东西连接在一起,而不需要样板。但是在测试中使用了许多不同的实现(通常是mock),通常使用手动连接,而不使用DI框架。如果这也是你的情况,那么你的直觉是正确的:如果DI框架扫描整个代码,接受默认/唯一的实现,并将其作为依赖项注入,那将是很好的。如果您的依赖注入框架提供了该功能,那么您是幸运的。如果没有,你必须自己实现它。
https://stackoverflow.com/questions/33583481
复制相似问题