最初に補足
完全版も参照のこと。
完全版のやりかたの場合、IServiceCollection.Configure()で登録すればIOptionalの形で、カスタムResolverに直接登録すればSettingの形で取得できる形になります。
やること
この例のように、カスタムIControllerActivatorを使用して、カスタムDependency Resolverで型付けされた構成を扱う場合について記述します。
型付けされた構成
ASP.NET Coreでは、設定ファイルの内容に対応するクラスを用意して、そのIOptions<T>をDependency Injectionで受け取ることが可能です。
まず、この例を記述します。
設定ファイル
以下のような設定のSmtpSettingsセクションについて、型付けされた形で扱えるようにします。
{
"Logging": {
"IncludeScopes": false,
"LogLevel": {
"Default": "Debug",
"System": "Information",
"Microsoft": "Information"
}
},
"SmtpSettings": {
"Host": "127.0.0.1",
"Port": 25
}
}
構成クラス
設定ファイルの内容について、型付けされた構成クラスとして以下を用意します。
public class SmtpSettings
{
public string Host { get; set; }
public int Port { get; set; }
}
初期化処理
IServiceCollectionのConfigure<T>()拡張メソッドにより、設定ファイルの内容を元にした構成クラスの登録ができます。
public void ConfigureServices(IServiceCollection services)
{
// Add framework services.
services.AddMvc();
// IOptions<T>でのインジェクション有効化
services.AddOptions();
services.Configure<SmtpSettings>(Configuration.GetSection("SmtpSettings"));
}
コントローラーでのDI
以下のように、型付けされた構成クラスをDIして使用できます。
public class SettingsController : Controller
{
private SmtpSettings SmtpSettings { get; }
public SettingsController(IOptions<SmtpSettings> options)
{
SmtpSettings = options.Value;
}
public IActionResult Index()
{
return View(SmtpSettings);
}
}
カスタムIControllerActivator使用時の問題点
コントローラーにDIされるオブジェクトは、IServiceCollectionではなくカスタムDependency Resolverに登録してやる必要があります。
登録するのはSmtpSettingsのインスタンスになりますが、Configuration.GetSection()で取得される設定ファイルの内容はIConfigurationSectionの形であり、この内容をSmtpSettingsに変換する必要があります。
IConfigurationSectionから構成クラスへの変換は以下の処理で行います。
var settings = new SmtpSettings();
Configuration.GetSection("SmtpSettings").Bind(settings);
IConfigurationSection.Bind()拡張メソッドにより、設定ファイルの内容を構成クラスのメンバにバインドできます。
なお、カスタムIControllerActivatorでSmtpSettingsのインスタンスを直接扱う場合、コントローラーではIOptions<SmtpSettings<ではなく、SmtpSettingsをインジェクションして貰う形となります。
うさコメ
カスタムDependency Resolver使用時の話としては、あとFromServicesAttributeの対応なんかもあるのよね(・∀・;)