問題なく設定ファイルを読み込む

この記事では、構成ファイルから設定を読み込む際の問題を検討します。 通常、開発者はSystem.Configuration名前空間の重量級で複雑なAPIを使用し、設定を段階的に読み取ります。 構成ファイルで読み取られるセクションが単純な構造(ネストなし)である場合、原則として、読み取りによって特別な問題は発生しません。 ただし、構成が複雑になったり、ネストされたサブセクションが表示されたりすると、解析は真の頭痛の種になります。 設定を簡単かつ迅速に読み取ってメモリに読み込むには、 ConfigurationParserライブラリが最適です。これにより、構成ファイルを操作する際のすべての困難が生じます。



設置



このライブラリは、 NuGetからダウンロードできます。 または、 GitHubからソースをダウンロードできます。



使用する



ライブラリの機能を実証するために、プログラムがいくつかの外部サービス、データベースに接続するための設定を必要とし、システムがシステム管理者にレターを送信できる必要があると想像してみましょう。 これらの設定は3つのセクションに分けることにしました。



システム構成
<ExternalSystemSettings> <AuthenticationSettings> <Login>DotNetCraft</Login> <Token>qwerty</Token> <Urls> <Url>https://github.com/DotNetCraft/ConfigurationParser</Url> <Url>https://github.com/DotNetCraft/ConfigurationParser</Url> </Urls> </AuthenticationSettings> <StaffSettings Token="{D0C148F7-83C0-41B0-8F18-B47CAB09AD99}" Url="https://github.com/DotNetCraft/ConfigurationParser"/> </ExternalSystemSettings> <DatabasesSettings> <MongoSettings ConnectionString="mongo.url" DatabaseName="DotNetCraft"/> <SqlSettings> <item key="TenantA"> <value> <SqlSettings ConnectionString="sql.TenantA.com"/> </value> </item> <item> <key>TenantB</key> <value> <SqlSettings> <ConnectionString>sql.TenantB.com</ConnectionString> </SqlSettings> </value> </item> </SqlSettings> </DatabasesSettings> <SmtpSettings Host="gmail.com" Sender="no-reply"> <Recipients>clien1@gmail.com;clien2@gmail.com;clien3@gmail.com</Recipients> </SmtpSettings>
      
      







次のステップは、システム設定を保存するクラスを作成することです。



構成クラス
  #region ExternalSystemSettings class ExternalSystemSettings { public AuthenticationServiceSettings AuthenticationSettings { get; set; } public StaffServiceSettings StaffSettings { get; set; } } class AuthenticationServiceSettings { public string Login { get; set; } public string Token { get; set; } public List<string> Urls { get; set; } } class StaffServiceSettings { public Guid Token { get; set; } public string Url { get; set; } } #endregion #region DatabasesSettings class DatabasesSettings { public MongoDatabaseSettings MongoSettings { get; set; } public Dictionary<string, SqlSettings> SqlSettings { get; set; } } class MongoDatabaseSettings { public string ConnectionString { get; set; } public string DatabaseName { get; set; } } class SqlSettings { public string ConnectionString { get; set; } } #endregion #region Smtp class SmtpSettings { public string Host { get; set; } public string Sender { get; set; } [CustomStrategy(typeof(SplitRecipientsCustomStrategy))] public List<string> Recipients { get; set; } } #endregion
      
      







構成ファイルで、ConfigurationParserを使用することを宣言する必要があります。



App.ConfigにconfigSectionsを取り込む
 <?xml version="1.0" encoding="utf-8" ?> <configuration> <configSections> <section name="ExternalSystemSettings" type="DotNetCraft.ConfigurationParser.SimpleConfigurationSectionHandler, DotNetCraft.ConfigurationParser" /> <section name="DatabasesSettings" type="DotNetCraft.ConfigurationParser.SimpleConfigurationSectionHandler, DotNetCraft.ConfigurationParser" /> <section name="SmtpSettings" type="DotNetCraft.ConfigurationParser.SimpleConfigurationSectionHandler, DotNetCraft.ConfigurationParser" /> </configSections></configuration>
      
      





これで、簡単かつ自然に構成を取得できます。



 ExternalSystemSettings externalSystemSettings = (dynamic)ConfigurationManager.GetSection("ExternalSystemSettings"); DatabasesSettings databasesSettings = (dynamic)ConfigurationManager.GetSection("DatabasesSettings");
      
      





コードを実行すると、設定を含む2つのオブジェクトが作成されます。 当然のことながら、 SmtpSettingsは読みません。 これは、ユーティリティの追加機能を実証するために行われます。



さまざまなプロジェクトで、さまざまな設定を構成ファイルに書き込んで、それらの操作方法に関する独自のロジックが必要になる場合があります。 このユーティリティは、新しい戦略を追加し、必要なすべてのシナリオをカバーすることにより、簡単に拡張できるように設計されています。 例として、 Recipientsセクションを見てみましょう。



 <Recipients>clien1@gmail.com;clien2@gmail.com;clien3@gmail.com</Recipients>
      
      





このセクションには、セミコロンで区切られた電子メールのリストが含まれています。 TKとクラスによると、各アドレスを配列内の個別の要素として記述する必要があります。 このタスクを実行するには、 SplitRecipientsCustomStrategyクラスを作成し、 ICustomMappingStrategyインターフェイスを実装する必要があります



ユーザー戦略
 class SplitRecipientsCustomStrategy : ICustomMappingStrategy { #region Implementation of ICustomMappingStrategy public object Map(string input, Type itemType) { string[] items = input.Split(';'); List<string> result = new List<string>(); result.AddRange(items); return result; } public object Map(XmlNode xmlNode, Type itemType) { string input = xmlNode.InnerText; return Map(input, itemType); } #endregion }
      
      





内部では、タスクに従ってセクションから値を解析するためのアルゴリズムを実装する必要があります。 値が属性から読み取られる場合、 Mapメソッド(文字列入力、type itemType)が呼び出され、値がセクションから読み取られる場合、 Map(XmlNode xmlNode、Type itemType)メソッドが呼び出されることに注意してください。 構成ファイルによると、値はセクションから読み取られます。



その後、RecipientsプロパティをCustomStrategy属性でマークする必要があります。CustomStrategy属性では、このフィールドで使用される「戦略」の種類を示す必要があります。



 [CustomStrategy(typeof(SplitRecipientsCustomStrategy))] public List<string> Recipients { get; set; }
      
      





以上で、メールの設定を確認できます。



 SmtpSettings smtpSettings = (dynamic)ConfigurationManager.GetSection("SmtpSettings");
      
      





ご覧のとおり、 ConfigurationParserを使用すると、構成ファイルから設定を読み取る作業が非常に便利になり、時間を大幅に節約できます。 同時に、新しい戦略が組み込まれているため、簡単に拡張できます。



このライブラリの別の機能について言及したいと思います。 これは、 PropertyMappingAttribute属性です。 構成ファイル内の要素の名前がプロパティの名前と一致しない場合に使用する必要があります。

たとえば、ユーザーの現在の住所が記録されるメールセクションがあります。

 <Email>clien1@gmail.com</Email>
      
      





ただし、この値を格納するクラスには、 UserEmailプロパティがあります。 設定が正しく考慮されるためには、 PropertyMappingAttribute属性でこのプロパティを変更する必要があります。

 [PropertyMapping("Email")] public string UserEmail { get; set; }
      
      





したがって、構成ファイル内の要素の名前は、プロパティの名前と一致する必要はありません。



ご質問やご提案がありましたら、コメントに書いてください。喜んでお答えします。



All Articles