Configurationオブジェクトにアクセスする単純な静的クラスが必要です。すべての構成情報は、スタートアップクラスの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;
上記と同じ原理に基づいたわずかに短いバージョン...
public Startup(IConfiguration configuration)
{
Configuration = configuration;
StaticConfig = configuration;
}
public static IConfiguration StaticConfig { get; private set; }
別の静的クラスで使用するには:
string connString = Startup.StaticConfig.GetConnectionString("DefaultConnection");
私は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...
}
}
静的クラスの使用を避け、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"];
}
}
StartUpクラスのセットアップDI
public class Startup {
public void ConfigureServices(IServiceCollection services) {
//...
services.AddTransient<IConfig, Config>();
...
}
}
そしてそのように使用します
public class TestUsage {
public TestUsage(IConfig config) {
_config = config;
}
readonly IConfig _config;
public string Username => _config.Username;
public string Password => _config.Password;
}
多くの研究の後、これは静的クラスからappsettings.json構成にアクセスするために(ASPNetCore 2.2で)動作しますが、何らかの理由でappsettings.development.jsonが正しくロードされなくなりましたが、それは私のプロジェクトでそれを台無しにするかもしれません。 reloadOnChangeは機能します。ボーナスとして、IHostingEnvironmentとIHttpContextAccessorもあります。これは機能しますが、最近、他の人が述べたようにパラダイムシフトに従うために、よりDIのアプローチに切り替えることにしました。
したがって、静的クラスでいくつかのDIのもの(構成を含む)にアクセスする多くの方法の1つを次に示します。
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"
}
}
これはすでに言われていますが、私はそれを言うつもりです。
静的クラスは、オブジェクト指向プログラミングのベストプラクティスではありません。この理由から、.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クラス内で静的プロパティを使用する必要がありますが、これは恐ろしいソリューションです。
以下は、これらを静的に参照することなく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からパラメーター値を渡すクラスがあります。
環境変数を構成として使用している場合 、構成オブジェクト経由ではなく、環境変数に直接アクセスできます。
using System;
namespace My.Example
{
public static class GetPaths
{
private static readonly string MyPATH =
Environment.GetEnvironmentVariable("PATH");
private static readonly string MySpecialPath =
Environment.GetEnvironmentVariable("PREFIX_SpecialPath");
...
}
}
個人的に私はこれで使用される方法が好きです link
基本的には、静的フィールドをオプションクラスに追加するだけです。
public class WeblogConfiguration
{
public static WeblogConfiguration Current;
public WeblogConfiguration()
{
Current = this;
}
}
次に、静的クラスで次のことができます。
WeblogConfiguration.Current
シンプルで非常に簡単