首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >ServiceCollection为IOptions返回null,即使GetSection正在工作

ServiceCollection为IOptions返回null,即使GetSection正在工作
EN

Stack Overflow用户
提问于 2017-09-03 03:25:01
回答 2查看 8.3K关注 0票数 11

我在手动构建一个IServiceProvider时遇到了困难,这将允许我的单元测试使用它来使用GetService<IOptions<MyOptions>>进行共享测试配置

我创建了一些单元测试来说明我的问题,如果它在回答问题时有用的话,那么它的回购也可以是在这里发现的

JSON

代码语言:javascript
运行
复制
{
  "Test": {
    "ItemOne":  "yes"
  }
}

选项类

代码语言:javascript
运行
复制
public class TestOptions
{
    public string ItemOne { get; set; }
}

测试

在这些测试中,ConfigureWithBindMethodConfigureWithBindMethod都失败了,SectionIsAvailable通过了。因此,据我所知,该部分是按预期从JSON文件中使用的。

代码语言:javascript
运行
复制
[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")时,将得到以下值

代码语言:javascript
运行
复制
{Microsoft.Extensions.Configuration.ConfigurationSection}
    Key: "Test"
    Path: "Test"
    Value: null

从表面上看,我假设值不应该为空,这使我认为我在这里可能遗漏了一些显而易见的东西,所以如果有人能发现我做错了什么,那就是天才。

谢谢!

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2017-09-03 20:53:53

若要在服务集合中使用选项,需要添加使用选项collection.AddOptions();所需的服务。

这应该能起作用:

代码语言:javascript
运行
复制
[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);
}
票数 26
EN

Stack Overflow用户

发布于 2021-09-21 22:43:11

首先,请投kloarubeek的答案。我还没熬过去就被困住了。

我有一个不同的转折。

这不起作用

代码语言:javascript
运行
复制
        MyCustomConfigurationPoco concreteMyCustomConfigurationPoco =
            new MyCustomConfigurationPoco();
        configuration.GetSection("MyJsonName")
            .Bind(concreteMyCustomConfigurationPoco);

        servColl.AddSingleton<MyCustomConfigurationPoco>(concreteMyCustomConfigurationPoco);

但是,改变到这一点确实奏效了:

代码语言:javascript
运行
复制
        MyCustomConfigurationPoco concreteMyCustomConfigurationPoco =
            new MyCustomConfigurationPoco();
        configuration.GetSection("MyJsonName")
            .Bind(concreteMyCustomConfigurationPoco);

/*我的警告在这里*/

代码语言:javascript
运行
复制
        servColl.Configure<MyCustomConfigurationPoco>(option =>
        {
            option.SomeScalarPropertyOne = concreteMyCustomConfigurationPoco.SomeScalarPropertyOne;
            option.SomeScalarPropertyTwo = concreteMyCustomConfigurationPoco.SomeScalarPropertyTwo;
        });

你可能会问:“这和另一个答案有什么不同?”

实际上,在将它注入IoC之前,我必须从IoC以外的地方设置一个值。

所以我在上面的地方。

/*我的警告在这里*/

想象一下这样的代码

代码语言:javascript
运行
复制
option.SomeScalarPropertyTwo = AnotherThing.GetSomeScalarPropertyTwo();

因此,在将MyCustomConfigurationPoco (实例化)注入IoC之前,我必须对它进行操作。

但是现在我的"getter“代码工作如下所示:

代码语言:javascript
运行
复制
            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));
            }
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/46019988

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档