2017-06-20 77 views
2

我正在使用Autofac JSON文件为我的项目中的相同接口注册两个类。在AUTOFAC中为同一接口使用不同的JSON配置文件

如果我做这样的事情:

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

它的工作原理。

我需要分离文件来配置它们。我想念什么?

回答

3

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

当你拥有的配置,Microsoft.Extensions.Configuration的方式要处理它是覆盖设置,您层上的另一顶一个配置提供商。

在简单情况下,说你有两种配置:

{ 
    "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文件结合起来,只是通过单独加载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); 

如果配置为空或丢失,它只是不会注册任何东西。如果它在那里,它会的。如果您想重写某些东西或将其添加到您的处理程序集以获得较好的分辨率,则应该可以正常工作。

+0

有没有简单的方法来覆盖第一个JSON的一部分与第二个? (授予密钥匹配) – marsop

相关问题