【问题标题】:Microsoft.Extensions.Options Do you have to keep passing it through the full stack manuallyMicrosoft.Extensions.Options 您是否必须手动将其通过完整堆栈
【发布时间】:2018-12-26 04:43:35
【问题描述】:

我第一次用 appsettings.json 代替 app.config 所以请原谅我找不到的可能愚蠢的问题在我的研究中一个令人满意的解决方案。

我有一个以 .Net Core 2.0 Web API 为前端的解决方案,其中依赖项目将我的解决方案分解为多个类库层。我需要从底层持久层类库中获取存储在顶层 appsettings.json(在我的 Web API 下)中的连接字符串。

我找到this article 一步一步地解释它。终于让它工作了。

注意:我用 connectionString 测试了这个功能,但我还需要其他变量,我打算稍后再做。

我的问题是,一旦我实现了所需的构造函数:

public Data(IOptions<ConnectionStrings> connectionStrings)
{
  ConnectionStrings = connectionStrings;
}

我必须手动将IOptions 对象一直传递到堆栈中。

Data date = new Data(ConnectionStrings);

有没有类似于ConfigurationManager 给你的不需要我一直传递IOptions 对象的解决方案?

我肯定做错了什么,不是吗?

【问题讨论】:

  • 不,这就是想法 - 避免静态/单例等。它们使现场和测试变得糟糕。如果需要(或部分需要),您应该传递它们。还要阅读IOptionSnapshot 等,以了解为什么静力学不会(总是)起作用。话虽如此,没有什么可以阻止您“缓存”在 static 变量中检索到的值并从那时起使用它(但至少不推荐)。
  • @Christian.K,将此作为答案发布,我会这样标记。

标签: c# .net-core app-config appsettings


【解决方案1】:

在构建我的第一个 dotnet core 2 应用程序时,我也有类似的担忧。我想出的解决方案是配置依赖注入将T解析为IOptions&lt;T&gt;.Value,例如:

            services.AddTransient<SomeOptions>(sp => 
                sp.GetService<IOptions<SomeOptions>>().Value);

如果您对需要在构造函数中提供 SomeOptions 的对象使用依赖注入,则此方法效果很好。如果您手动“更新”对象,则不会真正提供太多价值。

我不完全确定您的应用程序是什么样的,但从您上面的示例中,您有一个 Data 类,它在构造函数中采用 IOptions&lt;ConnectionStrings&gt; 参数。

在您的启动中给出以下代码:

// I don't have your entire project - just looking at your link above, I came up with this
services.Configure<ConnectionStrings> 
   (Configuration.GetSection("ConnectionStrings"));

services.AddTransient<ConnectionStrings>(sp => 
            sp.GetService<IOptions<ConnectionStrings>>().Value);

services.AddTransient<Data>();

你可以这样定义你的数据类:

public class Data
{
    private readonly ConnectionStrings _connectionStrings;

    public Data(ConnectionStrings connectionStrings)
    {
        //I don't know what you need to do with this here - just guessing
        _connectionStrings = connectionStrings;
    }
}

你可以这样定义你的控制器类:

public class SomeController
{
    private readonly Data _data;

    public SomeController(Data data) 
    {
       _data = data;
    }

    public IActionResult Get() 
    {
        // do something with _data here
        // don't new it up - it gets injected!
    }
    ...
}

【讨论】:

  • 您能否提供更多信息?在我的 Web API 的 startup.cs 类中添加 services.AddTransiant<...>
  • 当然——没有你所有的代码,这是我能想到的最好的!希望能帮助你更好地理解依赖注入!
  • 感谢@BlakeH,但我的 Data 类实际上在不同的项目中。我认为 Christian.K 上面的答案是我所做的所有研究中的正确答案。
  • 我不知道为什么一个班级在不同的项目中很重要 - 但听起来你有一个计划!
  • 感谢@BlakeH,我特别担心必须通过每个后续项目的构造函数传递应用程序设置(包括连接字符串)。根据我过去使用 ConfigurationManager 的经验,这感觉不对,但我认为 Christian.K 给出的理由是有道理的。在不同的项目中有代码只是突出了我试图解决的问题,谢谢
猜你喜欢
  • 2018-10-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-07-01
  • 2018-02-03
  • 2021-10-11
  • 2013-12-17
  • 2013-06-11
相关资源
最近更新 更多