我在手动构建一个IServiceProvider时遇到了困难,这将允许我的单元测试使用它来使用GetService<IOptions<MyOptions>>进行共享测试配置
我创建了一些单元测试来说明我的问题,如果它在回答问题时有用的话,那么它的回购也可以是在这里发现的。
JSON
{
"Test": {
"ItemOne": "yes"
}
}选项类
public class TestOptions
{
public string ItemOne { get; set; }
}测试
在这些测试中,ConfigureWithBindMethod和ConfigureWithBindMethod都失败了,SectionIsAvailable通过了。因此,据我所知,该部分是按预期从JSON文件中使用的。
[TestClass]
public class UnitTest1
{
[TestMethod]
public void ConfigureWithoutBindMethod()
{
var collection = new ServiceCollection();
var config = new ConfigurationBuilder()
.AddJsonFile("test.json", optional: false)
.Build();
collection.Configure<TestOptions>(config.GetSection("Test"));
var services = collection.BuildServiceProvider();
var options = services.GetService<IOptions<TestOptions>>();
Assert.IsNotNull(options);
}
[TestMethod]
public void ConfigureWithBindMethod()
{
var collection = new ServiceCollection();
var config = new ConfigurationBuilder()
.AddJsonFile("test.json", optional: false)
.Build();
collection.Configure<TestOptions>(o => config.GetSection("Test").Bind(o));
var services = collection.BuildServiceProvider();
var options = services.GetService<IOptions<TestOptions>>();
Assert.IsNotNull(options);
}
[TestMethod]
public void SectionIsAvailable()
{
var collection = new ServiceCollection();
var config = new ConfigurationBuilder()
.AddJsonFile("test.json", optional: false)
.Build();
var section = config.GetSection("Test");
Assert.IsNotNull(section);
Assert.AreEqual("yes", section["ItemOne"]);
}
}可能有助于指出
在“立即”窗口中调用config.GetSection("Test")时,将得到以下值
{Microsoft.Extensions.Configuration.ConfigurationSection}
Key: "Test"
Path: "Test"
Value: null从表面上看,我假设值不应该为空,这使我认为我在这里可能遗漏了一些显而易见的东西,所以如果有人能发现我做错了什么,那就是天才。
谢谢!
发布于 2017-09-03 20:53:53
若要在服务集合中使用选项,需要添加使用选项collection.AddOptions();所需的服务。
这应该能起作用:
[TestMethod]
public void ConfigureWithoutBindMethod()
{
var collection = new ServiceCollection();
collection.AddOptions();
var config = new ConfigurationBuilder()
.AddJsonFile("test.json", optional: false)
.Build();
collection.Configure<TestOptions>(config.GetSection("Test"));
var services = collection.BuildServiceProvider();
var options = services.GetService<IOptions<TestOptions>>();
Assert.IsNotNull(options);
}发布于 2021-09-21 22:43:11
首先,请投kloarubeek的答案。我还没熬过去就被困住了。
我有一个不同的转折。
这不起作用
MyCustomConfigurationPoco concreteMyCustomConfigurationPoco =
new MyCustomConfigurationPoco();
configuration.GetSection("MyJsonName")
.Bind(concreteMyCustomConfigurationPoco);
servColl.AddSingleton<MyCustomConfigurationPoco>(concreteMyCustomConfigurationPoco);但是,改变到这一点确实奏效了:
MyCustomConfigurationPoco concreteMyCustomConfigurationPoco =
new MyCustomConfigurationPoco();
configuration.GetSection("MyJsonName")
.Bind(concreteMyCustomConfigurationPoco);/*我的警告在这里*/
servColl.Configure<MyCustomConfigurationPoco>(option =>
{
option.SomeScalarPropertyOne = concreteMyCustomConfigurationPoco.SomeScalarPropertyOne;
option.SomeScalarPropertyTwo = concreteMyCustomConfigurationPoco.SomeScalarPropertyTwo;
});你可能会问:“这和另一个答案有什么不同?”
实际上,在将它注入IoC之前,我必须从IoC以外的地方设置一个值。
所以我在上面的地方。
/*我的警告在这里*/
想象一下这样的代码
option.SomeScalarPropertyTwo = AnotherThing.GetSomeScalarPropertyTwo();因此,在将MyCustomConfigurationPoco (实例化)注入IoC之前,我必须对它进行操作。
但是现在我的"getter“代码工作如下所示:
IOptions<MyCustomConfigurationPoco> concreteMyCustomConfigurationPocoOptions =
servProv.GetService<IOptions<MyCustomConfigurationPoco>>();
if (null == concreteMyCustomConfigurationPocoOptions)
{
throw new ArgumentNullException(nameof(concreteMyCustomConfigurationPocoOptions));
}
MyCustomConfigurationPoco concreteMyCustomConfigurationPoco =
concreteMyCustomConfigurationPocoOptions.Value;
if (null == concreteMyCustomConfigurationPoco)
{
throw new ArgumentNullException(nameof(concreteMyCustomConfigurationPoco));
}https://stackoverflow.com/questions/46019988
复制相似问题