2015-11-07 121 views
3

我试图总是以模块化的方式设计我的应用程序。我希望能够在任何给定的交换模块。依赖注入模块化依赖注册

使用依赖注入模式允许我这样做。但是有些东西一直困扰我很多。

在大多数代码我来跨越存在其中接口被链接到所期望的接口的单个​​地方。例如在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>();   
} 

有任何图案,或最好的做法来做这种事情?我可以创建一些接口并加载该接口的所有实现,但我不确定这是否是实现此目的的最佳方式。

回答

2

是否有任何图案或最佳实践做这样的事情?

是,也不是。有Facade pattern,您可以为客户提供简化的API,而无需对API进行精细控制。 Facade模式并不明确地关注依赖注入,但如果这是一件有意义的事情,你总是可以提供默认的服务组合。我的文章DI Friendly Library中有更多细节。

这就是说,保持API开放,使门面只是您提供给客户的一个选项是非常重要的。如果您预先在库中编写了一个对象图,并且不提供任何方法来规避该默认构图,那么这样的库就是一个单一的黑盒子。来自依赖注入的所有外部好处都将消失,因为客户端将无法替换或扩展服务。

请遵循DI Friendly Library文章中列出的指导原则,但一定要避免Conforming Container anti-pattern

0

我要说的是,通道/地方配置您的DI的高度取决于你的DI框架。有些框架可以让你执行每个模块的配置,其他的需要一个全局配置。在后一种情况下,您可以手动委派您的子模块(只需将IServiceCollection传递给子模块配置代码)。

有关最佳实践:我很少看到DI的使用有多个生产实现。通常只有一种生产实施方式,而DI仅用于在没有样板的情况下将所有产品连接在一起。但许多不同的实现(通常是模拟)通常在没有DI框架的情况下通过手动连线进行测试。如果这也是你的情况,那么你的直觉就是对的:有一个DI框架可以扫描整个代码,采用默认的/唯一的实现并将其注入为依赖关系。如果你的DI框架提供了这个功能,那么你很幸运。如果不是,你必须自己实施它