gpt4 book ai didi

c# - 在 AUTOFAC 中对同一接口(interface)使用不同的 JSON 配置文件

转载 作者:太空狗 更新时间:2023-10-30 01:00:36 25 4
gpt4 key购买 nike

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

如果我这样做:

JSON 配置文件 1:

{
"components": [
{
"type": "Services.FirstProvider, Services",
"services": [
{
"type": "Services.IHotelProvider, Services"
}
],
"parameters": {
"username": "<user>",
"password": "<pwd>"
}
}
]
}

JSON 配置文件 2:

{
"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>"
}
}
]
}

有效。

我需要有单独的文件来配置它们。我想念什么?

最佳答案

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

当您有配置时,Microsoft.Extensions.Configuration 想要处理它的方式是覆盖设置,因为您将一个配置提供程序层叠在另一个之上。。。 p>

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

{
"my-key": "a"
}

{
"my-key": "b"
}

它不会创建所有可能值的数组;它将根据匹配的键( 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:捏造数组(不推荐)

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

{
"components": [
{
"type": "Services.FirstProvider, Services",
"services": [ ...]
}
]
}

您可以通过在第二个“覆盖”配置中放置一个虚拟的空元素来稍微“捏造”它:

{
"components": [
{
},
{
"type": "Services.SecondProvider, Services",
"services": [ ...]
}
]
}

我最后检查过,覆盖的东西只是附加的,所以空值不会删除以前设置的值。通过将第二个配置中的数组移动 1,它将更改键/值表示的扁平化版本,并且这两个数组应该按照您想要的方式“合并”。

但这很丑陋,我不会那样做。我只是想向您展示一种让它发挥作用的方法,以便您理解为什么您所做的不起作用。

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

与其尝试合并这两个 JSON 文件,不如创建两个单独的 IConfiguration通过单独加载 JSON 文件来获取对象。在两个不同的地方分别注册它们 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);

如果配置为空或丢失,它就不会注册任何东西。如果它在那里,它就会。如果您想覆盖某些东西或添加到您的处理程序集中以获得良好的效果 IEnumerable<T>分辨率,这应该有效。

关于c# - 在 AUTOFAC 中对同一接口(interface)使用不同的 JSON 配置文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44648817/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com