首页 > 解决方案 > 带有配置文件的 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 中尚不支持。

标签: .net-coreasp.net-core-2.0

解决方案


当我有多个客户端时,例如 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;
     }
}

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


推荐阅读