web-dev-qa-db-ja.com

.NET Coreで辞書にappsetting.jsonセクションを読み込む方法は?

.NET Coreのstartup.csで強く型付けされたオブジェクトにappsettings.jsonセクションをロードすることをよく知っています。例えば:

public class CustomSection 
{
   public int A {get;set;}
   public int B {get;set;}
}

//In Startup.cs
services.Configure<CustomSection>(Configuration.GetSection("CustomSection"));

//Inject an IOptions instance
public HomeController(IOptions<CustomSection> options) 
{
    var settings = options.Value;
}

Appsettings.jsonセクションがあり、キーと値のペアの数と名前は時間とともに変化します。したがって、新しいキーと値のペアではクラスのコードを変更する必要があるため、クラスのプロパティ名をハードコーディングすることは現実的ではありません。いくつかのキーと値のペアの小さなサンプル:

"MobileConfigInfo": {
    "appointment-confirmed": "We've booked your appointment. See you soon!",
    "appointments-book": "New Appointment",
    "appointments-null": "We could not locate any upcoming appointments for you.",
    "availability-null": "Sorry, there are no available times on this date. Please try another."
}

このデータをMobileConfigInfoディクショナリオブジェクトにロードし、IOptionsパターンを使用してMobileConfigInfoをコントローラーに注入する方法はありますか?

38
ChrisP

_startup.cs_クラスでConfiguration.Bind(settings);を使用できます

そしてあなたの設定クラスは次のようになります

_public class AppSettings
{
    public Dictionary<string, string> MobileConfigInfo
    {
        get;
        set;
    }
}
_

それが役に立てば幸い!

26
Hung Cao

次の構造フォーマットを使用します。

"MobileConfigInfo": {
    "Values": {
       "appointment-confirmed": "We've booked your appointment. See you soon!",
       "appointments-book": "New Appointment",
       "appointments-null": "We could not locate any upcoming appointments for you.",
       "availability-null": "Sorry, there are no available times on this date. Please try another."
 }
}

設定クラスを次のようにします。

public class CustomSection 
{
   public Dictionary<string, string> Values {get;set;}
}

次にこれを行います

services.Configure<CustomSection>((settings) =>
{
     Configuration.GetSection("MobileConfigInfo").Bind(settings);
});
27
code5

Dictionaryに変換したい人のために、

appsettings.json内のサンプルセクション

"MailSettings": {
    "Server": "http://mail.mydomain.com"        
    "Port": "25",
    "From": "[email protected]"
 }

次のコードは、スタートアップファイル内に配置する必要があります> ConfigureServicesメソッド:

public static Dictionary<string, object> MailSettings { get; private set; }

public void ConfigureServices(IServiceCollection services)
{
    //ConfigureServices code......

    MailSettings = Configuration.GetSection("MailSettings").GetChildren()
                  .ToDictionary(x => x.Key, x => x.Value);
}

これで、次のような場所から辞書にアクセスできます。

string mailServer = Startup.MailSettings["Server"];

1つの欠点は、すべての値が文字列として取得されることです。他のタイプを試すと、値はnullになります。

20
Amro

次のコードを使用できると思います。

var config =  Configuration.GetSection("MobileConfigInfo").Get<Dictionary<string, string>>(); 
13
macpak

最も簡単な方法は、サポートするディクショナリタイプから継承するように構成クラスを定義することです。

public class MobileConfigInfo:Dictionary<string, string>{
}

その後、起動と依存性注入のサポートは、他の構成タイプの場合とまったく同じになります。

7
Jeremy Lakeman

単純な(おそらくマイクロサービスの)アプリケーションの場合は、それをシングルトンとして追加できますDictionary<string, string>し、必要な場所に注入します。

var mobileConfig = Configuration.GetSection("MobileConfigInfo")
                    .GetChildren().ToDictionary(x => x.Key, x => x.Value);

services.AddSingleton(mobileConfig);

そして使用法:

public class MyDependantClass
{
    private readonly Dictionary<string, string> _mobileConfig;

    public MyDependantClass(Dictionary<string, string> mobileConfig)
    {
        _mobileConfig = mobileConfig;
    }

    // Use your mobile config here
}
4
ste-fu

私は以下の方法を使用します:

appsettings.json:

  "services": {
      "user-service": "http://user-service:5000/",
      "app-service": "http://app-service:5000/"
  } 

startup.cs:

  services.Configure<Dictionary<string, string>>(Configuration.GetSection("services"));

使用法:

private readonly Dictionary<string, string> _services;
public YourConstructor(IOptions<Dictionary<string, string>> servicesAccessor)
{
    _services = servicesAccessor.Value;
}
2
ErikXu

ASP.Net Core 2.1でのより複雑なバインディングの例として。 ドキュメント のように、ConfigurationBuilder.Get<T>()メソッドを使用する方がはるかに扱いやすいことがわかりました。

ASP.NET Core 1.1以降ではGetを使用できます。これはセクション全体で機能します。 Getは、Bindを使用するよりも便利です。

Startupメソッドで構成をバインドしました。

private Config Config { get; }

public Startup(IConfiguration Configuration)
{
    Config = Configuration.Get<Config>();
}

これはappsettingsファイルをバインドします:

{
    "ConnectionStrings": {
        "Accounts": "Server=localhost;Database=Accounts;Trusted_Connection=True;",
        "test": "Server=localhost;Database=test;Trusted_Connection=True;",
        "Client": "Server=localhost;Database={DYNAMICALLY_BOUND_CONTEXT};Trusted_Connection=True;",
        "Support": "Server=localhost;Database=Support;Trusted_Connection=True;"
    },
    "Logging": {
        "IncludeScopes": false,
        "LogLevel": {
            "Default": "Debug",
            "System": "Information",
            "Microsoft": "Information"
        }
    },
    "Plugins": {
        "SMS": {
            "RouteMobile": {
                "Scheme": "https",
                "Host": "remote.Host",
                "Port": 84567,
                "Path": "/bulksms",
                "Username": "username",
                "Password": "password",
                "Source": "CompanyName",
                "DeliveryReporting": true,
                "MessageType": "Unicode"
            }
        },
        "SMTP": {
            "GenericSmtp": {
                "Scheme": "https",
                "Host": "mail.Host",
                "Port": 25,
                "EnableSsl": true,
                "Username": "[email protected]",
                "Password": "password",
                "DefaultSender": "[email protected]"
            }
        }
    }
}

この構成構造に:

[DataContract]
public class Config
{
    [DataMember]
    public Dictionary<string, string> ConnectionStrings { get; set; }
    [DataMember]
    public PluginCollection Plugins { get; set; }
}

[DataContract]
public class PluginCollection
{
    [DataMember]
    public Dictionary<string, SmsConfiguration> Sms { get; set; }
    [DataMember]
    public Dictionary<string, EmailConfiguration> Smtp { get; set; }
}

[DataContract]
public class SmsConfiguration
{
    [DataMember]
    public string Scheme { get; set; }
    [DataMember]
    public string Host { get; set; }
    [DataMember]
    public int Port { get; set; }
    [DataMember]
    public string Path { get; set; }
    [DataMember]
    public string Username { get; set; }
    [DataMember]
    public string Password { get; set; }
    [DataMember]
    public string Source { get; set; }
    [DataMember]
    public bool DeliveryReporting { get; set; }
    [DataMember]
    public string Encoding { get; set; }
}

[DataContract]
public class EmailConfiguration
{
    [DataMember]
    public string Scheme { get; set; }
    [DataMember]
    public string Host { get; set; }
    [DataMember]
    public int Port { get; set; }
    [DataMember]
    public string Path { get; set; }
    [DataMember]
    public string Username { get; set; }
    [DataMember]
    public string Password { get; set; }
    [DataMember]
    public string DefaultSender { get; set; }
    [DataMember]
    public bool EnableSsl { get; set; }
}
2
derpasaurus

私(ASP.NET Core 3.0)で機能したのは、Startup.csConfigureServicesメソッドに以下を追加することだけです。

services.Configure<Dictionary<string, string>>(dict => Configuration.GetSection("MySectionName").GetChildren().ToList().ForEach(c => dict[c.Key] = c.Value));
1
Jesper Mygind