前言
我在我的一个应用程序中实现管理配置的方式是按照洋葱架构规则构建的,如下所示。
在这种特殊情况下,我正在考虑将管理配置(例如日志记录)作为基础设施问题,这意味着它显然不是我的应用程序核心的一部分。这是因为它是另一层。
哲学课程
要演示基础设施问题,请看下图:
* 图片来自Shawn J Lee的博客链接。
在这里您可以看到日志记录发生在基础架构切片或层中,我已经说过管理配置也是一个基础架构问题。
现在,如果您需要在架构中的任何地方获取配置管理器实现,您只需在构造函数中请求您的IApplicationConfig,并根据您最喜欢的DI container/framework 中的配置注入正确的实现。这称为Hollywood Principle 或更好的控制反转。
你说的唠叨够了吗?现在让我们直接进入技术演示...
实施概述
您已询问将实际实现放在何处。我会将这些位构造为:
困了是吗?现在让我们转向更高的档位。
实现示例
我将尝试在这里简要说明实际的实现细节。
域接口组件
这是您放置应用程序核心 - 以及其他层 - 将针对或使用的所有接口的层。
假设我们有IApplicationConfig.cs:
public interface IApplicationConfig
{
ConnectionStringSettingsCollection GetConnectionStrings();
}
配置组装
这是您可以实际实现IApplicationConfig 接口的地方。把它作为一个单独的程序集是有问题的,但它实际上只是一个实现细节,我个人将我所有的配置管理实现都存储在这里。
例如IApplicationConfig 的实现可以是ApplicationConfig.cs:
public class ApplicationConfig : IApplicationConfig
{
public ConnectionStringSettingsCollection GetConnectionStrings()
{
return ConfigurationManager.ConnectionStrings;
}
}
依赖解析组装
这是您将接口与所需实现“链接”的地方。这里我使用了 Ninject 并为其创建了一个 Ninject module,将其称为 ConfigModule,一个简单的例子:
public class ConfigModule : NinjectModule
{
Bind<IApplicationConfig>().To<ApplicationConfig>();
}
最后是命令行/网站程序集
通常这些是Composition Root 或构成对象图的应用程序的入口点。说了这么多,我们现在只需要加载我们的 Ninject 模块:
private static IKernel CreateKernel()
{
var kernel = new StandardKernel();
var modules = new List<INinjectModule>
{
new ConfigModule(),
new WhateverModule(),
...
};
kernel.Load(modules);
}
您需要添加命令行/网站程序集的参考
将接口契约和它的实现分开,这里你只需要添加对:
现在您可以在任何您想要的层中使用您的实现。
后记
这个例子取自我的一个实际应用,如果你不同意命名事物,我同意......这是not an easy thing来做的。