即使 GetSection 正在工作,ServiceCollection 也会为 IOptions 返回 null [英] ServiceCollection returns null for IOptions even though GetSection is working
问题描述
我在手动构建 IServiceProvider
时遇到问题,该 IServiceProvider
将允许我的单元测试使用它来使用 GetService
引入共享测试配置
我创建了一些单元测试来说明我的问题,也可以在找到这里 如果它有助于回答问题.
JSON
<代码>{测试": {ItemOne":是"}}
选项类
公共类TestOptions{公共字符串 ItemOne { 获取;放;}}
测试
在这些测试中,ConfigureWithBindMethod
和 ConfigureWithBindMethod
都失败了,其中 SectionIsAvailable
通过了.因此,据我所知,该部分正在按预期从 JSON 文件中使用.
[测试类]公共类 UnitTest1{[测试方法]public void ConfigureWithoutBindMethod(){var collection = new ServiceCollection();var config = new ConfigurationBuilder().AddJsonFile("test.json", 可选: false).建造();collection.Configure(config.GetSection("Test"));var services = collection.BuildServiceProvider();var options = services.GetService>();Assert.IsNotNull(options);}[测试方法]public void ConfigureWithBindMethod(){var collection = new ServiceCollection();var config = new ConfigurationBuilder().AddJsonFile("test.json", 可选: false).建造();collection.Configure(o => config.GetSection("Test").Bind(o));var services = collection.BuildServiceProvider();var options = services.GetService>();Assert.IsNotNull(options);}[测试方法]public void SectionIsAvailable(){var collection = new ServiceCollection();var config = new ConfigurationBuilder().AddJsonFile("test.json", 可选: false).建造();var section = config.GetSection("测试");Assert.IsNotNull(section);Assert.AreEqual("yes", section["ItemOne"]);}}
可能有用的指出
在即时窗口中调用 config.GetSection("Test")
时,我得到这个值
{Microsoft.Extensions.Configuration.ConfigurationSection}关键测试"路径:测试"值:空
从表面上看,我认为 Value 不应该为 null,这让我觉得我可能在这里遗漏了一些明显的东西,所以如果有人能发现我做错了什么,那就太天才了.
>谢谢!
要在你的服务集合中使用选项,你需要添加使用选项所需的服务 collection.AddOptions();
>
这应该可以解决问题:
[测试方法]public void ConfigureWithoutBindMethod(){var collection = new ServiceCollection();集合.AddOptions();var config = new ConfigurationBuilder().AddJsonFile("test.json", 可选: false).建造();collection.Configure(config.GetSection("Test"));var services = collection.BuildServiceProvider();var options = services.GetService>();Assert.IsNotNull(options);}
I'm having trouble manually constructing a IServiceProvider
that will allow my unit tests to use it to pull in shared test configuration using GetService<IOptions<MyOptions>>
I created some unit tests to illustrate my problems, also the repo for this can be found here if it's useful in answering the question.
The JSON
{
"Test": {
"ItemOne": "yes"
}
}
The Options Class
public class TestOptions
{
public string ItemOne { get; set; }
}
The Tests
Out of these tests ConfigureWithBindMethod
and ConfigureWithBindMethod
both fail, where SectionIsAvailable
passes. So the section is being consumed as expected from the JSON file as far as I can tell.
[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"]);
}
}
Possibly useful to point out
When calling config.GetSection("Test")
in the immediate window, I get this value
{Microsoft.Extensions.Configuration.ConfigurationSection}
Key: "Test"
Path: "Test"
Value: null
At face value I'd have assumed Value should not be null, which is leading me to think I may be missing something obvious here, so if anyone can spot what I'm doing wrong that'd be genius.
Thanks!
To use options in your service collection, you need to add the service required for using options collection.AddOptions();
This should do the trick:
[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);
}
这篇关于即使 GetSection 正在工作,ServiceCollection 也会为 IOptions 返回 null的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!