无需依赖注入即可访问配置

Los*_*les 21 c# .net-core

我想知道是否有一种方法可以在不使用依赖注入的情况下访问Configuration(Microsoft.Extensions.Configuration).我看到的只有一些例子是通过构造函数注入(使用IOptions或直接注入Configuration).

我的困境是我有一个实用类 - 而不是一个服务 - 它有静态方法来动态地做事.在一些静态方法中,我想动态地从appsettings.json中检索几个属性.由于这是一个严格的实用程序类,我不希望必须将此类注入需要使用该实用程序中的一个或两个方法的其他每个类.

关于如何在没有某种依赖注入的情况下访问appsettings.json的属性的任何想法.

仅供参考:使用c#和.net核心1.1

Hoo*_*ots 28

哇,有很多评论,为什么人们不回答问题而不是告诉别人他们不想做他们显然做的事情.无论如何,希望这将使两个阵营都满意.

如果您使用带有单个公共构造函数的标准AppSettings类,该构造函数采用可用于填充所有AppSettings属性的IConfiguration,则这将保留依赖注入的能力.

如果在构造函数的末尾我们设置一个指向当前AppSettings实例的静态属性'Current',这将允许我们通过static属性从该点开始访问设置,而无需进一步注入.

如果我们现在创建一个静态的默认'GetCurrentSettings'方法来从json文件中获取设置,这可以用作默认实例化,这样如果调用'Current'并将其设置为null,我们只需关闭并填充文件中的设置.这是我的意思的一个例子......

public class AppSettings
{
    private static AppSettings _appSettings;

    public string AppConnection { get; set; }

    public AppSettings(IConfiguration config)
    {
        this.AppConnection = config.GetValue<string>("AppConnection");

        // Now set Current
        _appSettings = this;
    }

    public static AppSettings Current
    {
        get
        {
            if(_appSettings == null)
            {
                _appSettings = GetCurrentSettings();
            }

            return _appSettings;
        }
    }

    public static AppSettings GetCurrentSettings()
    {
        var builder = new ConfigurationBuilder()
                        .SetBasePath(Directory.GetCurrentDirectory())
                        .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
                        .AddEnvironmentVariables();

        IConfigurationRoot configuration = builder.Build();

        var settings = new AppSettings(configuration.GetSection("AppSettings"));

        return settings;
    }
}
Run Code Online (Sandbox Code Playgroud)

因此,您可以在代码AppSettings.Current.AppConnection中的任何位置调用

如果已使用DI实例化,则将检索注入的版本,否则将从appsettings.json文件中获取默认版本.我怀疑它是否满足每个人,我不确定我是否已经很好地解释了它,但希望它有意义.

  • 加1为"为什么人们不回答问题".我很生病被告知我不应该做我想问的怎么做. (9认同)
  • +1 的原因与@ProfK 所说的相同。我确信他们正在努力帮助您改善代码风格,但我确实感受到了您的痛苦。每个人都认为你很笨,需要被告知你想问什么,这有点侮辱人。(在某些情况下它**实际上是**所以,但它的侮辱性永远不会减少。)他们应该陈述**你**问题的答案,然后提供替代方案。或者至少解释他们没有回答你的问题,并询问你是否希望看到另一种方法。另一方面,SO 是免费的,所以无论如何你得到的都比你付出的多,呵呵。 (2认同)
  • 我只是想补充一下,对于.NET Core的较新版本,您将需要包括以下软件包: Microsoft.Extensions.Configuration.FileExtensions;` (2认同)
  • 很好的答案,这可能有用的情况之一是在集成测试中,依赖注入不是一个选项。 (2认同)

Pro*_*ofK 8

我只是将config属性Startup设为静态:

public static IConfiguration Configuration { get; set; }
Run Code Online (Sandbox Code Playgroud)

现在,我只需使用即可访问它Startup.Configuration

  • 问题在于,现在公开了启动,并且对所有需要“静态”配置的用户都具有依赖性。IMO由于这是Startup类而不是预期的目的,因此这不是理想的。使用自定义AppSettings类的最新答案更合适,因为它在某种程度上模仿了专门为提供配置服务而建的内核前时代的ConfigurationManager.AppSettings。但是可以,如果您可以从代码中需要它的任何地方调用Startup.Configuration,那么您的解决方案就会起作用。 (2认同)

Ank*_*ori 6

我完全同意@Hoot建议的解决方案,但我对课程进行了一些修改。我修改了类,因为我需要传递动态键来获取相同的值。

配置类别:

public class ConfigHelper
    {

        private static ConfigHelper _appSettings;

        public string appSettingValue { get; set; }

        public static string AppSetting(string Key)
        {
          _appSettings = GetCurrentSettings(Key);
          return _appSettings.appSettingValue;
        }

        public ConfigHelper(IConfiguration config, string Key)
        {
            this.appSettingValue = config.GetValue<string>(Key);
        }

        public static ConfigHelper GetCurrentSettings(string Key)
        {
            var builder = new ConfigurationBuilder()
                            .SetBasePath(Directory.GetCurrentDirectory())
                            .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
                            .AddEnvironmentVariables();

            IConfigurationRoot configuration = builder.Build();

            var settings = new ConfigHelper(configuration.GetSection("AppSettings"), Key);

            return settings;
        }
    }
Run Code Online (Sandbox Code Playgroud)

Appsettings.Json 配置:

 "AppSettings": {
    "WebApplicationUrl": "http://localhost:0000/",
    "ServiceUrl": "http://localhost:0000/",
    "CommonServiceUrl": "http://localhost:0000/"
  }
Run Code Online (Sandbox Code Playgroud)

调用示例:

string ServiceUrl = ConfigHelper.AppSetting("ServiceUrl");
Run Code Online (Sandbox Code Playgroud)

所以从现在开始我们就可以传递动态密钥了。