将ConnectionStrings放在洋葱架构中的位置

时间:2016-05-12 13:37:48

标签: c# dependency-injection onion-architecture

我有一个接口IApplicationConfig,它基本上保存了ConnectionStrings,就像数据库,Blob存储和其他东西一样。对于每个"可执行文件"我的解决方案中的项目,如网站,命令行工具等。该接口的具体实现配置为通过依赖注入解决。

我的问题是,我应该在哪里放置这些IApplicationConfig - 实施?

我的web.config / app.config旁边的每个"可执行文件"项目? 或者在基础架构中,如Project1Config.csProject2Config.cs等?

2 个答案:

答案 0 :(得分:4)

前言

我在其中一个按照洋葱架构规则构建的应用程序中实现管理配置的方式如下。

在这种特殊情况下,我考虑将管理配置(例如日志记录)作为基础设施问题,这意味着它显然不属于我的应用程序核心。这是因为它是另一层。

哲学课程

为了证明基础设施问题,请看下面的图表:

Onion Architecture diagram

<子> *图片链接自Shawn J Lee的博客。

在这里,您可以看到日志记录发生在基础架构切片或层中,我已经说过管理配置也是一个基础设施问题。

现在,如果您需要掌握配置管理器实现,那么如果您需要掌握配置管理器实现,那么只需在构造函数中请求IApplicationConfig并按照您最喜欢的{{ 3}}。这称为DI container/framework或更好的控制反转。

你说呀呀呀呀?现在让我们直接进行技术演示......

实施概述

您已询问实际实施的位置。我将这些位构造为:

  • 应用核心层
    • 域接口程序集
  • 基础架构层
    • 配置程序集
    • 依赖性解决方案程序集
  • UI图层
    • 命令行程序集
    • 网站汇编

昏昏欲睡呃?让我们现在转向更高的档位。

实施例

我将在这里尝试说明实际的实现细节。

域接口程序集

这是您放置应用程序核心和其他层的所有接口将起作用或利用的所有接口的层。

说我们有IApplicationConfig.cs

public interface IApplicationConfig
{
    ConnectionStringSettingsCollection GetConnectionStrings();
}

配置程序集

在这里您可以获得IApplicationConfig界面的实际实现。将此作为一个单独的程序集是值得怀疑的,但它实际上只是一个实现细节,我个人在这里存储我所有的配置管理实现。

例如IApplicationConfig的实现可以是ApplicationConfig.cs

public class ApplicationConfig : IApplicationConfig
{
    public ConnectionStringSettingsCollection GetConnectionStrings()
    {
        return ConfigurationManager.ConnectionStrings;
    }
}

依赖关系解析程序集

这是你&#34;链接&#34;您的接口与所需的实现。在这里,我使用Ninject创建了一个Hollywood Principle,并将其称为ConfigModule,这是一个简单的例子:

public class ConfigModule : NinjectModule
{
    Bind<IApplicationConfig>().To<ApplicationConfig>();
}

最后是Commandline / Website程序集

通常这些是您组成对象图的应用程序的Ninject module或入口点。说完这个,我们现在只需要加载我们的Ninject模块:

private static IKernel CreateKernel()
{
    var kernel = new StandardKernel();

    var modules = new List<INinjectModule>
        {
            new ConfigModule(),
            new WhateverModule(),
            ...
        };

    kernel.Load(modules);
}

您需要添加命令行/网站程序集

的参考

将接口契约和它的实现分开,在这里你只需要添加对:

的引用
  • 依赖性解析程序集
  • 域接口程序集

现在,您可以在任何您想要的层中使用您的实现。

后记

这个例子来自我的实际应用,如果你不同意命名,我同意......它是Composition Root要做的。

答案 1 :(得分:0)

我会使接口更具体,以便它指定特定类或该程序集所需的内容,而不是应用程序。如果您的数据访问位于其自己的程序集中,那么ISettings应该特定于该程序集,而不是与主机应用程序共享。然后我还将实现放在需要它的程序集中。主机应用程序不应“知道”其他程序集使用的ISettings接口,也不应负责创建或提供实现。

如果要从app.config / web.config中读取实现,那么如果缺少这些设置,我会确保它会抛出详细的异常。这样,依赖于该程序集的人将不必猜测需要什么设置。

数据访问程序集的DI配置应该驻留在该数据访问程序集中,或者完全驻留在另一个程序集中。主机应用程序不应该“了解”其他程序集,因为它包含这些程序集的详细注册。主机应用程序只调用一些外部安装程序来注册该程序集的依赖项。

将DI配置放在自己的组件中也可能有意义。 (示例here使用Windsor。)这样,数据访问程序集是为依赖注入而构建的,但不依赖于任何一个DI容器。如有必要,您可以根据需要创建Windsor安装程序,Autofac安装程序等(取决于您的环境或可能过度的预期用途。)

相关问题