ASP.NET核心访问静态类的配置

时间:2017-08-25 16:16:23

标签: asp.net-core-mvc

我想要一个访问Configuration对象的简单静态类。所有配置信息都已从Startup类中的appsettings.json文件中读取。我只需要一种简单的方法来访问它。这可能吗?

namespace MyNamespace
{
    public static class Config
    {
        public string Username => Configuration["Username"];
        public string Password => Configuration["Password"];
    }
}

应用中的其他任何地方:

string username = Config.Username;
string password = Config.Password;

13 个答案:

答案 0 :(得分:8)

基于与上述相同的原理的简短版本...

public Startup(IConfiguration configuration)
{
    Configuration = configuration;
    StaticConfig = configuration;
}

public static IConfiguration StaticConfig { get; private set; }

要在另一个静态类中使用:

string connString = Startup.StaticConfig.GetConnectionString("DefaultConnection");

答案 1 :(得分:6)

我同意mcbowes,它在docs中,但第一个例子看起来更像你需要的......想要:

public class Program
{
    public static IConfigurationRoot Configuration { get; set; }
    public static void Main(string[] args = null)
    {
        var builder = new ConfigurationBuilder()
             .SetBasePath(Directory.GetCurrentDirectory())
            .AddJsonFile("appsettings.json");

        Configuration = builder.Build();

        Console.WriteLine($"option1 = {Configuration["option1"]}");

        // Edit:
        IServiceCollection services = new ServiceCollection();
        services.AddOptions();
        services.Configure<HelloWorldOptions>(_configuration.GetSection("HelloWorld"));
        // And so on...
    }
}

答案 2 :(得分:2)

请尝试避免使用静态类并使用DI

   AA/TT CC/GG AT 

    9     7     9
    5     13    5
    9     8     8

启动类中的设置DI

namespace MyNamespace {

  public interface IConfig {
    string Username { get; }
    string Password { get; }
  }


  public class Config : IConfig {
    public Config(IConfiguration configuration) {
      _configuration = configuration;
    }
    readonly IConfiguration _configuration;
    public string Username => _configuration["Username"];
    public string Password => _configuration["Password"];
  }


}

并像这样使用它

public class Startup {
  public void ConfigureServices(IServiceCollection services) {
    //...
    services.AddTransient<IConfig, Config>(); 
    ...
  }
}

答案 3 :(得分:2)

经过大量研究,该方法(在ASPNetCore 2.2中)可用于从静态类访问appsettings.json配置,但由于某些原因,appsettings.development.json无法再正确加载,但可能是我项目中的其他问题。 reloadOnChange确实起作用。作为奖励,它还具有IHostingEnvironment和IHttpContextAccessor。在这项工作奏效的同时,我最近决定改用更多的DI方法来遵循范式转换,就像其他人提到的那样。

因此,这是在静态类中访问某些DI东西(包括配置)的多种方法之一:

AppServicesHelper.cs:

public static class AppServicesHelper
{
        static IServiceProvider services = null;

        /// <summary>
        /// Provides static access to the framework's services provider
        /// </summary>
        public static IServiceProvider Services
        {
            get { return services; }
            set
            {
                if (services != null)
                {
                    throw new Exception("Can't set once a value has already been set.");
                }
                services = value;
            }
        }

        /// <summary>
        /// Provides static access to the current HttpContext
        /// </summary>
        public static HttpContext HttpContext_Current
        {
            get
            {
                IHttpContextAccessor httpContextAccessor = services.GetService(typeof(IHttpContextAccessor)) as IHttpContextAccessor;
                return httpContextAccessor?.HttpContext;
            }
        }

        public static IHostingEnvironment HostingEnvironment
        {
            get
            {
                return services.GetService(typeof(IHostingEnvironment)) as IHostingEnvironment;
            }
        }

        /// <summary>
        /// Configuration settings from appsetting.json.
        /// </summary>
        public static MyAppSettings Config
        {
            get
            {
                //This works to get file changes.
                var s = services.GetService(typeof(IOptionsMonitor<MyAppSettings>)) as IOptionsMonitor<MyAppSettings>;
                MyAppSettings config = s.CurrentValue;

                return config;
            }
        }
    }
}

Startup.cs:

public Startup(IHostingEnvironment env)
{
            var builder = new ConfigurationBuilder()
                .SetBasePath(env.ContentRootPath)
                .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
                .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: true)
                .AddEnvironmentVariables();
            Configuration = builder.Build();
 }

 public void ConfigureServices(IServiceCollection services)
 {
//...

        services.AddHttpContextAccessor();//For HttpContext.

        // Register the IOptions object
        services.Configure<MyAppSettings>(Configuration.GetSection(nameof(MyAppSettings)));

        //Explicitly register the settings object by delegating to the IOptions object so that it can be accessed globally via AppServicesHelper.
        services.AddSingleton(resolver => resolver.GetRequiredService<IOptionsMonitor<MyAppSettings>>().CurrentValue);
 }

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
//...
   AppServicesHelper.Services = app.ApplicationServices;
//...
}

控制器:

public class MyController: Controller
{
   public MyController()
   {
   }

   public MyAppSettings Config => AppServicesHelper.Config;

   public async Task<IActionResult> doSomething()
   {
            testModel tm = await myService.GetModel(Config.Setting_1);
            return View(tm);
   }
}

另一个类库:

public static class MyLibraryClass
{
     public static string GetMySetting_ => AppServicesHelper.Config.Setting_1; 
     public static bool IsDev => AppServicesHelper.HostingEnvironment.IsDevelopment();
}

MyAppSettings.cs是任何映射到appsettings.json中MyAppSettings部分的类:

public class MyAppSettings
{
    public string Setting_1 {get;set;}
}

appsettings.json:

{
  "Logging": {
    "LogLevel": {
      "Default": "Warning"
    }
  },
  "AllowedHosts": "*",
  "MyAppSettings": {
      "Setting_1": "something"
   }
 }

答案 4 :(得分:1)

您可以使用Signleton模式从任何地方访问您的配置

public class ConnectionStrings
{
    private ConnectionStrings()
    {
    }

    public static ConnectionStrings Instance => new ConnectionStrings();
    public string DatabaseConnection { get; set; }
}

以及您的启动课程

public class Startup
{
    private readonly IConfiguration configuration;

    public Startup(IConfiguration configuration)
    {
        this.configuration = configuration;
        configuration.GetSection("ConnectionStrings").Bind(ConnectionStrings.Instance);
    }

    public void ConfigureServices(IServiceCollection services)
    {
    }

    public void Configure(IApplicationBuilder app)
    {
    }
}

答案 5 :(得分:0)

已经说过了,但我要说出来。

静态类不是面向对象编程的最佳实践。我认为出于这个原因,.Net Core为我们提供了一种通过Dependency Inject获取值的方法。这是我从研究中注意到的,但我也在推测。作为开发人员,我们需要遵循这种模式转变,以便正确使用.Net Core。

Options Pattern是静态配置的不错选择。在您的情况下,它将如下所示:

appsettings.json

{
  "Username": "MyUsername",
  "Password": "Password1234"
}

SystemUser.cs

public class SystemUser 
{
  public string Username { get; set; } = "";
  public string Password { get; set; } = "";
}

Startup.cs

services.Configure<SystemUser>(Configuration);

要使用SystemUser类,请执行以下操作。

TestController.cs

public class TestController : Controller 
{
  private readonly SystemUser systemUser;

  public TestController(IOptionsMonitor<SystemUser> systemUserOptions)
  {
    this.systemUser = systemUserOptions.CurrentValue;
  }

  public void SomeMethod() 
  {
    var username = this.systemUser.Username; // "MyUsername"
    var password = this.systemUser.Password; // "Password1234"
  }
}

即使我们没有使用静态类,我也认为这是满足您需求的最佳选择。否则,您可能必须在Startup类内使用静态属性,这是一个令人恐惧的解决方案imo。

答案 6 :(得分:0)

这是一种从NET.Core页面获取配置值的方法,而不必静态引用这些值,但是仍然可以将其传递给从非静态类调用的其他静态函数。

在非静态类的顶部添加以下内容:

private readonly IConfiguration _configuration;

然后在构造函数中引入现有配置作为该函数的输入: IConfiguration configuration

然后将配置分配给构造函数中的只读变量: _configuration = configuration;

以下是其外观的示例:

public class IndexModel : PageModel
{
    private readonly IConfiguration _configuration;

    public IndexModel(IConfiguration configuration)
    {
        _configuration = configuration;
    }
}

此后,您可以通过引用_configuration引用该类中任何函数的配置,甚至可以将其传递给您从其他类调用的其他静态函数:

public async Task OnGetAsync()
{
    AnotherClass.SomeFunction(_configuration);
}

然后在被调用的静态类中,我可以使用配置值:

public static string SomeFunction(IConfiguration configuration)
{
    string SomeValue = configuration.GetSection("SomeSectionOfConfig")["SomeValue"];
}

我有一个类,该类调用一些用于查看和修改数据的存储过程,并使用此方法从appsettings.json传递参数值。

答案 7 :(得分:0)

If you are using environment variables as your configuration,您可以直接访问环境变量,而不必通过配置对象。

[19-06-14 14:40:00:463 EDT] Week Number: 1 -  Current Week: Jan 01    Next Week: Jun 08
[19-06-14 14:40:00:464 EDT] Week Number: 2 -  Current Week: Jan 08    Next Week: Jun 22
[19-06-14 14:40:00:464 EDT] Week Number: 3 -  Current Week: Jan 22    Next Week: Jul 13
[19-06-14 14:40:00:465 EDT] Week Number: 4 -  Current Week: Feb 12    Next Week: Aug 09
[19-06-14 14:40:00:466 EDT] Week Number: 5 -  Current Week: Mar 12    Next Week: Sep 16
[19-06-14 14:40:00:467 EDT] Week Number: 6 -  Current Week: Apr 16    Next Week: Oct 28
[19-06-14 14:40:00:468 EDT] Week Number: 7 -  Current Week: May 28    Next Week: Dec 16
[19-06-14 14:40:00:468 EDT] Week Number: 8 -  Current Week: Jul 16    Next Week: Feb 10
[19-06-14 14:40:00:469 EDT] Week Number: 9 -  Current Week: Sep 10    Next Week: Apr 13
[19-06-14 14:40:00:470 EDT] Week Number: 10 -  Current Week: Nov 12    Next Week: Jun 21
[19-06-14 14:40:00:471 EDT] Week Number: 11 -  Current Week: Jan 21    Next Week: Sep 06
[19-06-14 14:40:00:471 EDT] Week Number: 12 -  Current Week: Apr 07    Next Week: Nov 30

答案 8 :(得分:0)

我个人喜欢此link

中使用的方法

本质上,它只是向您的options类添加了一个静态字段。

 public class WeblogConfiguration
 {
    public static WeblogConfiguration Current;

    public WeblogConfiguration()
    {
        Current = this;
    }
} 

然后可以在任何静态类中进行以下操作:

WeblogConfiguration.Current

简单而直接

答案 9 :(得分:0)

我认为您可以使用扩展功能,诸如此类

public static string ConfigToSomeThing(this IConfiguration config, int value)
        {
            return config[value.ToString()] ?? "";
        }

然后在任何地方,只需注入IConfiguration并使用扩展方法

_systemConfiguration.ConfigToSomeThing(123);

答案 10 :(得分:0)

我是在下课时创建的:


    /// <summary>
    /// 
    /// </summary>
    public static class ConfigurationManager
    {
        /// <summary>
        /// 
        /// </summary>
        public sealed class ConfigurationManagerAppSettings
        {
            /// <summary>
            /// 
            /// </summary>
            internal ConfigurationManagerAppSettings() { }

            /// <summary>
            /// 
            /// </summary>
            /// <param name="key"></param>
            /// <returns></returns>
            public string this[string key] => (TheConfiguration ?? throw new Exception("Set ConfigurationManager.TheConfiguration in Startup.cs")).GetSection($"AppSettings:{key}").Value;
        }

        /// <summary>
        /// 
        /// </summary>
        public static IConfiguration? TheConfiguration { get; set; }

        /// <summary>
        /// 
        /// </summary>
        public static readonly ConfigurationManagerAppSettings AppSettings = new ConfigurationManagerAppSettings();
    }

及以下代码:

public class Startup
    {
        public Startup(IConfiguration configuration) {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services) {
            ConfigurationManager.TheConfiguration = Configuration;

答案 11 :(得分:-4)

考虑使用here指令进行ASP.NET核心配置。

您可以创建一个类来存储配置设置,然后访问值,如下所示:

_config.UserName

在启动 - 配置服务:

services.Configure<Config>(Configuration.GetSections("General"));

然后在您需要的地方注入您的物品:

IOptions<Config> config

答案 12 :(得分:-5)

IConfiguration可以在项目的任何位置进行注入。但在静态类的情况下,我正在使用的选项,也许只是接近...... var Configuration = new ConfigurationBuilder() .AddUserSecrets<Startup>() .Build(); 并且,您可以添加所需的部分,例如在上面的代码块中,我添加了'UserSecrets'。