ASP.NET Coreコンフィギュレーションチュートリアルの読み出しコンフィギュレーション情報

12817 ワード

「配置」という字といえば、ほとんどだと思います.NET開発者の頭の中には2つの特殊なファイルの姿が浮かび上がる.それは私たちがこれ以上よく知っているappだ.configとweb.configは、構造化された構成情報をこの2つのファイルに定義することに長年慣れています.着きました.NET Coreの時、私たちが慣れている多くのものが変わりました.その中には構成を定義する方法も含まれています.総じて言えば、新しい構成システムはより軽量で、より拡張性が高く、多様なデータソースをサポートすることが最大の特徴です.メモリの変数を構成のデータソースとして使用したり、永続化されたファイルやデータベースに定義したりすることができます.
多くの人がこの新しい設計を採用した構成システムに接触したことがないため、皆さんに感官的な認識を与えるために、私たちはまずプログラミングの角度からそれを初体験します.コンフィギュレーション用のAPIは、コンフィギュレーションモデルに対応するインタフェースを持つコンフィギュレーション、コンフィギュレーションBuilder、コンフィギュレーションProviderの3つのオブジェクトに関連します.この3つのオブジェクト間の関係は明確で、Configurationオブジェクトはプログラミング中に使用される構成情報を担持し、ConfigurationProviderは構成情報の元のデータソースのプロバイダであり、両者の間のコミュニケーションはConfigurationBuilderによって行われ、ConfigurationProviderによってソースデータを抽出してConfigurationオブジェクトに変換される.
一、キー値対として構成を読み取るほとんどの場合、構成情報は全体的に構造化された階層関係を持っているが、「原子」構成項目は最も簡単な「キー値対」の形で表現され、キーと値は文字列であり、次に、キー値対として構成を読み取る方法を簡単な例で示す.ASPを作成します.NET Coreのコンソールアプリケーション、project.jsonでは、「Microsoft.Extensions.Configuration」というNuGetパッケージへの依存を以下のように追加し、このパッケージに構成モデルを実装します.

{
  ...
   "dependencies": {
   "Microsoft.Extensions.Configuration": "1.0.0-rc1-final"
  },
 }

私たちのアプリケーションでは、設定によって日付/時間の表示フォーマットを設定する必要があると仮定し、4つの属性がDateTimeオブジェクトの4つの表示フォーマット(それぞれ長い日付/時間と短い日付/時間)を表すDateTimeFormatSettingsクラスを定義します.

public class DateTimeFormatSettings
 {
    public string LongDatePattern { get; set; }
    public string LongTimePattern { get; set; }
    public string ShortDatePattern { get; set; }
   public string ShortTimePattern { get; set; }
   //    
 }

DateTimeFormatSettingsの4つの属性で表される日付/時間表示フォーマットを構成形式で制御することを望んでいるので,構造関数を定義した.次のコードフラグメントに示すように、コンストラクション関数は、関連する構成情報のコンフィギュレーションオブジェクトを正式に担持するIConfigurationインタフェースタイプのパラメータを有する.コンフィギュレーションオブジェクトのインデックスを呼び出し、対応するコンフィギュレーションアイテムのKeyを指定してValueを取得します.

public class DateTimeFormatSettings
  {
   //    
   public DateTimeFormatSettings (IConfiguration configuration)
    {
      this.LongDatePattern   = configuration["LongDatePattern"];
     this.LongTimePattern   = configuration["LongTimePattern"];
     this.ShortDatePattern  = configuration["ShortDatePattern"];
      this.ShortTimePattern  = configuration["ShortTimePattern"];
   }
 }

現在の構成を表すDateTimeFormatSettingsオブジェクトを作成するには、関連する構成情報を格納するコンフィギュレーションオブジェクトを取得する必要があります.前述したように、コンフィギュレーションオブジェクトはコンフィギュレーションBuilderによって作成され、元の構成情報は対応するコンフィギュレーションProviderによって読み込まれるので、コンフィギュレーションオブジェクトを作成する正しいプログラミング方法は、まずコンフィギュレーションBuilderオブジェクトを作成し、その後、コンフィギュレーションProviderオブジェクトを1つ以上追加することです.最後に、コンフィギュレーションビルダーを使用して、必要なコンフィギュレーションオブジェクトを作成します.
上記のプログラミングモードに従って、コンソールアプリケーションで以下のプログラムを作成しました.コンフィギュレーションBuilderのタイプのオブジェクトを作成し、そのAddメソッドを呼び出して追加したコンフィギュレーションProviderはMemoryConfigurationProviderのタイプのオブジェクトです.MemoryConfigurationProviderは、メモリ内のオブジェクトを使用して元の構成情報を提供します.具体的には、これらの元の構成情報は、要素タイプがKeyValue Pairのセットに保存されます.最終的にConfigurationBuilderのBuildメソッドを呼び出して、DateTimeFormatSettingsオブジェクトを作成するために必要なConfigurationを取得します.

public class Program
 {
    public static void Main(string[] args)
    {
      Dictionary source = new Dictionary
      {
        ["LongDatePattern"]   = "dddd, MMMM d, yyyy",
        ["LongTimePattern"]   = "h:mm:ss tt",
        ["ShortDatePattern"]  = "M/d/yyyy",
        ["ShortTimePattern"]  = "h:mm tt"
      };
      IConfiguration configuration = new ConfigurationBuilder()
          .Add(new MemoryConfigurationProvider(source))
          .Build();
  
      DateTimeFormatSettings settings = new DateTimeFormatSettings(configuration);
      Console.WriteLine("{0,-16}: {1}", "LongDatePattern", settings.LongDatePattern);
      Console.WriteLine("{0,-16}: {1}", "LongTimePattern", settings.LongTimePattern);
      Console.WriteLine("{0,-16}: {1}", "ShortDatePattern", settings.ShortDatePattern);
      Console.WriteLine("{0,-16}: {1}", "ShortTimePattern", settings.ShortTimePattern);
   }
 }

構成に基づいて作成されたDateTimeFormatSettingsオブジェクトと構成元のデータの関係を検証するために、4つのプロパティをコンソールに出力します.このプログラムが実行されると、コンソールに次のような出力が生成され、私たちが提供した構成の真実な反映であることがわかります. LongDatePattern : dddd, MMMM d, yyyy  LongTimePattern : h:mm:ss tt  ShortDatePattern: M/d/yyyy  ShortTimePattern: h:mm tt
二、構造化された構成の実際の項目を読み取る構成の多くは構造化された階層を持っているため、構成モデルのコンフィギュレーションオブジェクトにもこのような構造がある.構造化された構成はツリー階層を持ち、コンフィギュレーションオブジェクトはこの構成ツリーを構成するノードを表し、この構成ツリーはルートノードであるコンフィギュレーションオブジェクトによって体現することができる.キー値ペアとして表現される原子構成項目は、一般に、リーフノードとしてのコンフィギュレーションオブジェクトに存在し、リーフノードでないコンフィギュレーションは、サブノードのセットを含み、各サブノードは同じコンフィギュレーションオブジェクトである.
次に、階層化された構成を定義して読み出す方法を例として説明します.前節の適用シーンに沿って、日付/時間のフォーマットだけでなく、通貨を表すDecimalタイプなどの他のデータ型のフォーマットも設定する必要があります.この目的のために、次のCurrencyDecimalFormatSettingsクラスを定義します.このクラスのプロパティDigitsとSymbolは、それぞれ小数点以下の桁数と通貨記号を表し、1つのCurrencyDecimalFormatSettingsオブジェクトは、構成を表すコンフィギュレーションオブジェクトを使用して作成されます.

 {
    public int   Digits { get; set; }
  public string Symbol { get; set; }
  
    public CurrencyDecimalFormatSettings(IConfiguration configuration)
   {
     this.Digits = int.Parse(configuration["Digits"]);
      this.Symbol = configuration["Symbol"];
   }
 }

異なるデータ型に対するフォーマットを表すFormatSettingsという別のタイプを定義した.次のコードクリップに示すように、2つのプロパティDateTimeとCurrencyDecimalは、それぞれ日付/時間と通貨番号のフォーマットを表します.FormatSettingsは、IConfigurationインタフェースのパラメータタイプを持つコンストラクション関数であり、両方のプロパティがこのコンストラクション関数で初期化されています.これら2つの属性を初期化するには、現在のコンフィギュレーションの「サブコンフィギュレーション・セクション」を使用し、コンフィギュレーション・セクション名を指定してGetSectionメソッドを呼び出すことで得られることに注意してください.

public class FormatSettings
{
  public DateTimeFormatSettings      DateTime { get; set; }
   public CurrencyDecimalFormatSettings   CurrencyDecimal { get; set; }
  
   public FormatSettings(IConfiguration configuration)
    {
      this.DateTime = new DateTimeFormatSettings(configuration.GetSection("DateTime"));
      this.CurrencyDecimal = new CurrencyDecimalFormatSettings(configuration.GetSection("CurrencyDecimal"));
    }
}

上記の例では、MemoryConfigurationProviderオブジェクトを使用して元の構成情報を提供します.元の構成情報をロードする要素タイプがKeyValue Pairの集合であるため、元の構成は物理ストレージ上でツリー化された階層を持たないため、構造化されたコンフィギュレーションオブジェクトを最終的に提供するにはどうすればよいのでしょうか.実は簡単で、MemoryConfigurationProviderオブジェクトは構成情報を簡単な「データ辞書」としてしか記憶できないが、コンフィギュレーションツリーにコンフィギュレーションオブジェクトが現れる経路をKeyとすれば、このデータ辞書は論理的に実際に木の構造を持っている.実際にMemoryConfigurationProviderはこのようにしています.これは私たちが以下に示すプログラムに現れています.

class Program
 {
   static void Main(string[] args)
   {
     Dictionary source = new Dictionary
     {
       ["Format:DateTime:LongDatePattern"]   = "dddd, MMMM d, yyyy",
       ["Format:DateTime:LongTimePattern"]   = "h:mm:ss tt",
       ["Format:DateTime:ShortDatePattern"]   = "M/d/yyyy",
       ["Format:DateTime:ShortTimePattern"]   = "h:mm tt",
 
       ["Format:CurrencyDecimal:Digits"]   = "2",
       ["Format:CurrencyDecimal:Symbol"]   = "$",
     };
     IConfiguration configuration = new ConfigurationBuilder()
         .Add(new MemoryConfigurationProvider(source))
         .Build();
 
     FormatSettings settings = new FormatSettings(configuration.GetSection("Format"));
     Console.WriteLine("DateTime:");
     Console.WriteLine("\t{0,-16}: {1}", "LongDatePattern", settings.DateTime.LongDatePattern);
     Console.WriteLine("\t{0,-16}: {1}", "LongTimePattern", settings.DateTime.LongTimePattern);
     Console.WriteLine("\t{0,-16}: {1}", "ShortDatePattern", settings.DateTime.ShortDatePattern);
     Console.WriteLine("\t{0,-16}: {1}
", "ShortTimePattern", settings.DateTime.ShortTimePattern); Console.WriteLine("CurrencyDecimal:"); Console.WriteLine("\t{0,-16}: {1}", "Digits", settings.CurrencyDecimal.Digits); Console.WriteLine("\t{0,-16}: {1}", "Symbol", settings.CurrencyDecimal.Symbol); } }

上のコードクリップに示すように、MemoryConfigurationProviderオブジェクトを作成するために使用されるディクショナリオブジェクトには6つの基本的な構成項目が含まれており、論理的にツリー化された階層を持つために、Keyは実際に各構成項目が配置ツリーにあるパスを体現しており、パスはコロン(":")で分割されています.プログラム変更が実行されると、コンソールに次のような出力結果が表示されます.

DateTime:
    LongDatePattern : dddd, MMMM d, yyyy
    LongTimePattern : h:mm:ss tt
     ShortDatePattern: M/d/yyyy
    ShortTimePattern: h:mm tt
 
 CurrencyDecimal:
    Digits     : 2
    Symbol     : $

三、構造化構成を直接オブジェクトにバインドする本当のプロジェクト開発の過程で、私たちは直接読み出した構成を直接使用することはなく、私たちが示した2つのインスタンスのように、対応するタイプ(DateTimeFormatSettings、CurrencyDecimalSettings、FormatSettingsなど)を作成することによって、関連する構成オプション(Option)のセットを定義する傾向があります.コンフィギュレーションオプション(Option)を定義するこれらのタイプをOptionタイプと呼びます.上記の例では、これらのパッケージ構成のオブジェクトを作成するために、手動で構成を読み取る形式を採用しています.定義された構成項目が多すぎると、構成項目を1つずつ読み取るのは非常に煩雑な作業です.
1つのオブジェクトについて、そのプロパティをサブノードと見なす場合、1つのオブジェクトはコンフィギュレーションオブジェクトに似たツリー階層構造を有します.あるOptionタイプの構造に基づいて構成を定義したり、逆に構成の構造に基づいてこのOptionタイプを定義したりすると、Optionタイプの属性メンバーはある構成セクションに1つ1つの関係を持ち、原則として構成情報を自動的に特定のOptionオブジェクトにバインドすることができます.
ASP.NET Coreは、構成のOptionモデル(OptionModel)に対して、構成からOptionオブジェクトへのバインドを実現するのに役立ち、次に簡単なプレゼンテーションを行います.Optionモデルは、「Microsoft.Extensions.OptionModel」というNuGetパッケージに実装されています.このほか、Optionモデルを使用するには依存注入方式を採用する必要があります.したがって、アプリケーションに対応する依存を以下のように追加する必要があります.

 {
  ...
  "dependencies": {
  "Microsoft.Extensions.OptionsModel"    : "1.0.0-rc1-final",
  "Microsoft.Extensions.DependencyInjection"  : "1.0.0-rc1-final"
  },
 }

Optionモデルの自動バインドメカニズムにより、構成情報を手動で読み込む必要がなくなり、FormatSettings、DateTimeFormatSettings、CurrencyDecimalSettingsのコンストラクション関数を削除し、その属性メンバーのみを保持します.プログラムエントリとしてのMainメソッドでは,このフォーマットを表すFormatSettingsオブジェクトを以下のように作成する.

 class Program
{
   static void Main(string[] args)
   {
     Dictionary source = new Dictionary
     {
      ["Format:DateTime:LongDatePattern"] = "dddd, MMMM d, yyyy",
      ["Format:DateTime:LongTimePattern"] = "h:mm:ss tt",
      ["Format:DateTime:ShortDatePattern"] = "M/d/yyyy",
       ["Format:DateTime:ShortTimePattern"] = "h:mm tt",
 
       ["Format:CurrencyDecimal:Digits"] = "2",
       ["Format:CurrencyDecimal:Symbol"] = "$",
    };
    IConfiguration configuration = new ConfigurationBuilder()
         .Add(new MemoryConfigurationProvider(source))
         .Build()
         .GetSection("Format"));
 
     IOptions optionsAccessor = new ServiceCollection()
       .AddOptions()
       .Configure(configuration)
      .BuildServiceProvider()
      .GetService>();
 
    FormatSettings settings = optionsAccessor.Value;
 
     Console.WriteLine("DateTime:");
     Console.WriteLine("\t{0,-16}: {1}", "LongDatePattern",settings.DateTime.LongDatePattern);
     Console.WriteLine("\t{0,-16}: {1}", "LongTimePattern",settings.DateTime.LongTimePattern);
     Console.WriteLine("\t{0,-16}: {1}", "ShortDatePattern",settings.DateTime.ShortDatePattern);
     Console.WriteLine("\t{0,-16}: {1}
", "ShortTimePattern",settings.DateTime.ShortTimePattern); Console.WriteLine("CurrencyDecimal:"); Console.WriteLine("\t{0,-16}: {1}", "Digits",settings.CurrencyDecimal.Digits); Console.WriteLine("\t{0,-16}: {1}", "Symbol",settings.CurrencyDecimal.Symbol); } }

上記のコードクリップに示すように、ServiceCollectionオブジェクトを作成し、拡張メソッドAddOptionsを呼び出してOptionモデルのサービスに登録します.次に、Configureメソッドを呼び出して、FormatSettingsというOptionタイプを対応するConfigurationオブジェクトにマッピングします.最後に、このServiceCollectionオブジェクトを使用してServiceProviderを生成し、GetServiceメソッドを呼び出して、関連する構成をバインドしたFormatSettingsオブジェクトを返すIOptionsタイプのオブジェクトを取得します.
以上が本文のすべての内容で、みんなの学習に役立つことを望みます.