即使 GetSection 正在工作,ServiceCollection 也会为 IOptions 返回 null [英] ServiceCollection returns null for IOptions even though GetSection is working

查看:26
本文介绍了即使 GetSection 正在工作,ServiceCollection 也会为 IOptions 返回 null的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在手动构建 IServiceProvider 时遇到问题,该 IServiceProvider 将允许我的单元测试使用它来使用 GetService> 引入共享测试配置

我创建了一些单元测试来说明我的问题,也可以在找到这里 如果它有助于回答问题.

JSON

<代码>{测试": {ItemOne":是"}}

选项类

公共类TestOptions{公共字符串 ItemOne { 获取;放;}}

测试

在这些测试中,ConfigureWithBindMethodConfigureWithBindMethod 都失败了,其中 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屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆