.net core 带有配置文件的点网内核中的IoC/DI

.net core 带有配置文件的点网内核中的IoC/DI,.net-core,asp.net-core-2.0,.net Core,Asp.net Core 2.0,所以我一直在与点网核心合作。 我让IoC/DI与“代码er up”一起工作 我发现了“按环境”调整的能力 “按环境”在您需要调整时非常有效…按…嗯…环境 不起作用的是“按客户”的不同DI需求 假设我有一个产品。它的目标是与客户的数据库对话,每个客户的数据库都是完全不同的 我想把这些数据转换成一个“标准” (顺便说一句,这是一个示例) 我将编写一个接口:ICCustomerSDataAdapter 我会写一封信 AcmeAdapter:ICCustomerSDataAdapter MomAndPo

所以我一直在与点网核心合作。 我让IoC/DI与“代码er up”一起工作

我发现了“按环境”调整的能力

“按环境”在您需要调整时非常有效…按…嗯…环境

不起作用的是“按客户”的不同DI需求

假设我有一个产品。它的目标是与客户的数据库对话,每个客户的数据库都是完全不同的

我想把这些数据转换成一个“标准”

(顺便说一句,这是一个示例)

我将编写一个接口:ICCustomerSDataAdapter

我会写一封信

AcmeAdapter:ICCustomerSDataAdapter

MomAndPopsShopAdapter:ICCustomersDataAdapter

(等等,等等)

对于Microsoft Unity,当我使用xml配置部署代码(在每个客户的不同位置)时,交换不同的客户机适配器非常简单。
这不是“按环境”,因为我所有的客户都有开发、登台和生产环境

有没有人用DI解决过这种类型的IoC/DI,并且不涉及像这样的黑客行为


enc.IsEnvironment(“AcmeProduction”),其中我混合/结合了不同客户和环境的关注点。(当我有多个客户端时,例如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
}
我将在
环境变量中创建一个名为“client\u id”的参数

通过以上配置,在
程序.cs
中,我可以了解“客户端”和“环境”:

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;
     }
}
公共类启动
{
公共IConfiguration配置{get;}
公共启动(IConfiguration配置)
{
配置=配置;
}
public void配置服务(IServiceCollection服务)
{
....
配置数据库(配置);
}
...
}
公共静态void配置适配器(此IServiceCollection服务,IConfiguration配置)
{
var adapterType=configuration.GetSection(“适配器”).Value;//此值从A/B/C.env.json读取
开关(适配器类型)
{
案例“acme”:
services.AddSingleton();
打破
案例“momAndPopsShop”:
services.AddSingleton();
打破
违约:
//日志或抛出错误
打破
}
}

我不确定这是否是一个好的做法,但到目前为止,我是如何为不同的客户端和环境配置我的应用程序的。希望此方法可以帮助您找到更好的解决方案。(我认为会有更好的方法做到这一点)

但我不知道这种方法是否被视为“混合/组合不同客户和环境的关注点”。…因为我仍然在使用client&env访问不同的设置,并且DII感谢这种尝试…也许这是最好的方法。但是你最终会做开关/案例陈述,因此你必须当你得到一个新的“客户”时,重新编译代码。这看起来像是一个倒退(框架代码)。我知道这比“每个环境”要少,但在考虑全局软件问题时,这似乎并不太牵强。是的。这种方法要求在每次有新客户机时重新编译,以及如果我们想要更改现有客户机的实现