ASP.NET 5を学習するための基本的なアプリを書いています。veryがわかりにくい1つの領域は構成です。 ASP.NET 5より前は、次のことができました。
var settingValue = ConfigurationManager.AppSettings["SomeKey"];
このようなコード行をコード全体に散在させます。さて、vNextの世界では、次のようなconfig.jsonファイルがあります。
config.json
{
"AppSettings": {
"SomeKey":"SomeValue"
}
}
次に、Startup.csに次のものがあります。Startup.cs
public IConfiguration Configuration { get; set; }
public Startup(IHostingEnvironment environment)
{
Configuration = new Configuration()
.AddJsonFile("config.json");
}
そこから、私は完全に困惑しています。 /src/Website/Code/Models/MyClass.csにMyClass.csがあります。
MyClass.cs
public class MyClass
{
public string DoSomething()
{
var result = string.Empty;
var keyValue = string.Empty; // TODO: What do I do here? How do I get the value of "AppSettings:SomeKey"?
return result;
}
}
「AppSettings:SomeKey」の値を取得するにはどうすればよいですか?
構成を直接読み取るのではなく、OptionsModel
を使用することを強くお勧めします。強い型付けされたモデルを構成にバインドできます。
例は次のとおりです。 GitHub.com/aspnet/Options/test/Microsoft.Extensions.Options.Test/OptionsTest.cs
特定のケースでは、モデルを作成します。
class AppSettings {
public string SomeSetting {get;set;}
}
そして、それを設定にバインドします:
var config = // The configuration object
var options = ConfigurationBinder.Bind<AppSettings>(config);
Console.WriteLine(options.SomeSetting);
そうすれば、設定がどこから来たのか、どのように保存されているのか、どのような構造なのかを心配する必要はありません。オプションモデルを事前定義するだけで、魔法が発生します。
ASP.NET 5はDependency Injectionを多用するため、Dependency Injectionも使用している場合、これは非常に簡単です。サンプルMVC6プロジェクトを調べると、これがどのように機能するかを確認できます。
まず、プロパティで定義されたクラスAppSettingsがあります。これは、クラスがサポートするオプションの厳密に型指定されたバージョンです。サンプルプロジェクトでは、これにはSiteTitleのみが含まれています。
public class AppSettings
{
public string SiteTitle { get; set; }
}
次に、このクラスはConfigureServicesの依存関係注入によって初期化されます。 Configuration
は、Startupクラスのコンストラクターで作成したものです。
public void ConfigureServices(IServiceCollection services)
{
services.Configure<AppSettings>(Configuration.GetSubKey("AppSettings"));
// ...
}
次に、クラスが依存性注入コンテナーによってインスタンス化されていると仮定すると、IOptionsを要求するだけで取得できます。たとえば、コントローラーには次のものがあります。
public class HomeController
{
private string _title;
public HomeController(IOptions<AppSettings> settings)
{
_title = settings.Options.SiteTitle;
}
}
私は、ASP.NET 5依存性注入を使用しています。
config.json:
{
"random": "Hello World!"
}
startup.cs:
public class Startup
{
public Startup(IHostingEnvironment env, IApplicationEnvironment appEnv)
{
var builder = new ConfigurationBuilder(appEnv.ApplicationBasePath)
.AddJsonFile("config.json");
Configuration = builder.Build();
}
public IConfiguration Configuration { get; set; }
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc();
services.AddSingleton<IConfiguration>(sp => { return Configuration; });
}
public void Configure(IApplicationBuilder app)
{
app.UseMvc(routes =>
{
routes.MapRoute(name: "default", template: "{controller=Home}/{action=Index}/{id?}");
});
}
}
コントローラ:
public class HomeController : Controller
{
IConfiguration config;
public HomeController(IConfiguration config)
{
this.config = config;
}
public IActionResult Index()
{
var template = "<Marquee>{0}</Marquee>";
var content = string.Format(template, config.Get("random"));
return Content(content, "text/html");
}
}
これを使って:
var value = Configuration.Get("AppSettings:SomeKey");
このブログ投稿 に基づきます。コロンはドット表記に似ており、階層内のナビゲーションに使用されます。
ASP.NETには依存性注入が組み込まれていますが、MyClassのインスタンスが1つだけ必要な場合は、DIコンテナーを設定する代わりに、それを新しいものにできます。
public IConfiguration Configuration { get; set; }
public Startup(IHostingEnvironment environment)
{
Configuration = new Configuration()
.AddJsonFile("config.json");
//generally here you'd set up your DI container. But for now we'll just new it up
MyClass c = new MyClass(Configuration.Get("AppSettings:SomeKey"));
}
public class MyClass
{
private readonly string Setting; //if you need to pass multiple objects, use a custom POCO (and interface) instead of a string.
public MyClass(string setting) //This is called constructor injection
{
Setting = setting;
}
public string DoSomething()
{
var result = string.Empty;
//Use setting here
return result;
}
}