Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/333.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在AUTOFAC中为同一接口使用不同的JSON配置文件_C#_Autofac - Fatal编程技术网

C# 在AUTOFAC中为同一接口使用不同的JSON配置文件

C# 在AUTOFAC中为同一接口使用不同的JSON配置文件,c#,autofac,C#,Autofac,我正在使用Autofac JSON文件为我的项目中的同一接口注册两个类 如果我这样做: JSON配置文件1: { "components": [ { "type": "Services.FirstProvider, Services", "services": [ { "type": "Services.IHotelProvider, Services" } ], "parameter

我正在使用Autofac JSON文件为我的项目中的同一接口注册两个类

如果我这样做:

JSON配置文件1:

{
  "components": [
    {
      "type": "Services.FirstProvider, Services",
      "services": [
        {
          "type": "Services.IHotelProvider, Services"
        }
      ],
      "parameters": {
        "username": "<user>",
        "password": "<pwd>"
      }
    }
  ]
}
{
  "components": [
    {
      "type": "Services.SecondProvider, Services",
      "services": [
        {
          "type": "Services.IHotelProvider, Services"
        }
      ],
      "parameters": {
        "key": "<key>",
      }
    }
  ]
}
config.AddJsonFile("First/FirstProviderConfig.json");
config.AddJsonFile("Second/SecondProviderConfig.json");
我可以看到只有
SecondProvider
已注册。和转换注册:

config.AddJsonFile("Second/SecondProviderConfig.json");
config.AddJsonFile("First/FirstProviderConfig.json");
仅注册了
FirstProvider

如果我尝试在同一文件中注册它们:

{
  "components": [
    {
      "type": "Services.FirstProvider, Services",
      "services": [
        {
          "type": "Services.IHotelProvider, Services"
        }
      ],
      "parameters": {
        "username": "<user>",
        "password": "<pwd>"
      }
    },
    {
      "type": "Services.SecondProvider, Services",
      "services": [
        {
          "type": "Services.IHotelProvider, Services"
        }
      ],
      "parameters": {
        "key": "<key>"
      }
    }
  ]
}
{
“组成部分”:[
{
“类型”:“Services.FirstProvider,Services”,
“服务”:[
{
“类型”:“Services.IHotelProvider,Services”
}
],
“参数”:{
“用户名”:“”,
“密码”:”
}
},
{
“类型”:“Services.SecondProvider,Services”,
“服务”:[
{
“类型”:“Services.IHotelProvider,Services”
}
],
“参数”:{
“密钥”:”
}
}
]
}
它起作用了


我需要有单独的文件来配置它们。我错过了什么?

这里的关键点是,您现在正在使用Microsoft.Extensions.Configuration作为配置文件的基础,这意味着配置在某种程度上受Microsoft.Extensions.Configuration行为的控制

当您进行配置时,Microsoft.Extensions.configuration想要处理它的方式是在将一个配置提供程序分层到另一个配置提供程序上时覆盖设置

在简单的情况下,假设您有两种配置:

{
  "my-key": "a"
}

它不会创建一个包含所有可能值的数组;它将根据匹配的键(
my key
)在第一个键上分层第二个键,并覆盖值
b

解析JSON配置时,它会将所有内容平铺成键/值对。XML也是如此。之所以这样做,是因为配置支持环境变量、INI文件和各种其他备份存储

对于上述非常简单的文件,您可以

my-key == b
又好又平。看看更复杂的事情:

{
  "top": {
    "simple-item": "simple-value",
    "array-item": ["first", "second"]
  }
}
它变平了,就像:

top:simple-item == simple-value
top:array-item:0 == first
top:array-item:1 == second
注意数组(“有序集合”)是如何变平的吗?每个项目都会自动分配一个伪“键”,该键具有基于0的索引

现在考虑两个配置文件将如何分层。如果我有上面更复杂的配置,然后把这个

{
  "top": {
    "array-item": ["third"]
  }
}
那一个变平了

top:array-item:0 == third
看到我要去哪里了吗?将覆盖配置的图层覆盖在第一个图层上,可以得到:

top:simple-item == simple-value
top:array-item:0 == third
top:array-item:1 == second
数组不合并,键/值设置覆盖

您可以在JSON表示中看到它们,但它们都只是键/值对。

您有两种选择来尝试修复此问题

选项1:伪造阵列(不推荐)

由于您的第一个配置是(简化的):

您可以通过在第二个“override”配置中放置一个伪空元素来潜在地“伪造它”:

上一次我检查时,覆盖只是加法,所以空值不会删除以前设置的值。通过将第二个配置中的数组移位1,它将更改键/值表示的展开版本,并且两个数组应该按照您想要的方式“合并”

但那很难看,我不会那么做。我只是想向你展示一种方法,让你明白为什么你所做的不起作用

选项2:两个独立的配置模块(推荐)

不要试图组合两个JSON文件,只需通过分别加载JSON文件创建两个独立的
IConfiguration
对象即可。在两个不同的
ConfigurationModule
注册中分别注册它们。如果任何一个配置为空,它都不应该爆炸

var first = new ConfigurationBuilder();
first.AddJsonFile("autofac.json", optional: true);
var firstModule = new ConfigurationModule(first.Build());
var second = new ConfigurationBuilder();
second.AddJsonFile("autofac-overrides.json", optional: true);
var secondModule = new ConfigurationModule(second.Build());
var builder = new ContainerBuilder();
builder.RegisterModule(firstModule);
builder.RegisterModule(secondModule);

如果配置为空或丢失,它将不会注册任何内容。如果它在那里,它会的。如果您想要覆盖某些内容或添加到处理程序集以获得nice
IEnumerable
解析,那么这应该是可行的。

有没有一种简单的方法可以用第二个json覆盖第一个json的一部分?(假设钥匙匹配)
{
  "components": [
    {
      "type": "Services.FirstProvider, Services",
      "services": [ ...]
    }
  ]
}
{
  "components": [
    {
    },
    {
      "type": "Services.SecondProvider, Services",
      "services": [ ...]
    }
  ]
}
var first = new ConfigurationBuilder();
first.AddJsonFile("autofac.json", optional: true);
var firstModule = new ConfigurationModule(first.Build());
var second = new ConfigurationBuilder();
second.AddJsonFile("autofac-overrides.json", optional: true);
var secondModule = new ConfigurationModule(second.Build());
var builder = new ContainerBuilder();
builder.RegisterModule(firstModule);
builder.RegisterModule(secondModule);