.net-core - 带有配置文件的 Dot Net Core 中的 IoC/DI
问题描述
所以我一直在使用 Dot Net Core。我让 IoC/DI 使用“code er up”。
而且我发现可以调整“按环境”的能力。
当您需要调整时,“按环境”非常有用……通过……嗯……环境。
不起作用的是“客户”的不同 DI 需求。
假设我有一个产品。它的目标是与客户的数据库对话,每个客户的数据库是完全不同的。
我想把这些数据翻译成“标准”。
(这是一个插图示例,顺便说一句)。
我会写一个接口:ICustomersDataAdapter
我会写一个
AcmeAdapter : ICustomersDataAdapter
MomAndPopsShopAdapter : ICustomersDataAdapter
(等等等等)
使用 Microsoft Unity,当我使用它们的 xml 配置部署代码(在每个客户的不同位置)时,更换不同的客户端适配器是微不足道的。
这不是“按环境”,因为我所有的客户都有开发、登台和生产环境。
有没有人用 DI 解决了这种类型的 IoC/DI,并且不涉及 hacky 的东西,比如
enc.IsEnvironment("AcmeProduction") 我混合/组合不同客户和环境的关注点。(<< 嘘)
DotNetCore 以多种不同的方式经过深思熟虑。
但这一个,不知道它是如何被忽视的。
https://asp.net-hacker.rocks/2018/09/27/customizing-aspnetcore-03-dependency-injection.html
也许您想在应用程序外部的配置文件中配置服务,在 XML 或 JSON 文件中,而不是仅在 C# 中
这是各种 DI 容器中的常见功能,但在 ASP.NET Core 中尚不支持。
解决方案
当我有多个客户端时,例如 A、B 和 C,我会根据不同的代理和环境创建不同的 JSON 文件:
A.Development.json
,A.Staging.json
,A.Production.json
B.Development.json
,B.Staging.json
,B.Production.json
C.Development.json
,C.Staging.json
,C.Production.json
在每个 JSON 文件中,它看起来像
{
"adapter" : "acme" // it can be "acme" or "momAndPopsShop", based on requirement
}
我将在Environment Variables
.
通过上面的配置,在里面Program.cs
,我可以知道'client'和'environment':
var clientId = Environment.GetEnvironmentVariable("client_id"); // clientId will be A,B or C
var env = hostingContext.HostingEnvironment;
var settingFile = $"{clientId}.{env}.json"; // the exact client & env
// config is IConfigurationBuilder
config.AddJsonFile("appsettings.json", true, true) // add default app settings
.AddJsonFile(settingFile, true, true); // add customized client settings
到目前为止,我已经为客户端和环境添加了自定义设置。接下来,在 DI 部分,我将读取 IConfiguration 并根据设置注入相应的服务。
public class Startup
{
public IConfiguration Configuration { get; }
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public void ConfigureServices(IServiceCollection services)
{
....
services.ConfigureDatabase(Configuration);
}
...
}
public static void ConfigureAdapter(this IServiceCollection services, IConfiguration configuration)
{
var adapterType = configuration.GetSection("adapter").Value; // this value is read from A/B/C.env.json
switch (adapterType)
{
case "acme":
services.AddSingleton<ICustomersDataAdapter, AcmeAdapter>();
break;
case "momAndPopsShop":
services.AddSingleton<ICustomersDataAdapter, MomAndPopsShopAdapter>();
break;
default:
//log or throw error
break;
}
}
我不太确定这是否是一个好习惯,但到目前为止,这是我为不同的客户端和环境配置我的应用程序的方式。希望此方法可以帮助您找到更好的解决方案。(我认为会有更好的方法来做到这一点)
推荐阅读
- node.js - Firebase Firestore 错误:Dialogflow 参数中的“无效使用类型‘未定义’作为 Firestore 参数”
- sas - 在 proc 报告中仅获取特定的组换行符
- python-3.x - 使用测试装置作为类方法的测试 (PyTest)
- sbt - sbt 在编译运行时代码时运行自定义任务
- c# - 如何通过 REST API 连接到 iCloud Drive?
- javascript - 有没有办法让 GMail 插件隐藏/禁用发送按钮
- python - 根据条件将多个列值设置为 NaN
- c++ - Windows:检测右 alt 是否在当前布局中生成 Ctrl+Alt (AltGr)
- gitea - gitea - 创建回购 API
- go - 如何模块化处理函数和路由