Ich möchte eine einfache statische Klasse, die auf das Konfigurationsobjekt zugreift. Alle Konfigurationsinformationen sind bereits aus der Datei appsettings.json in der Startup-Klasse eingelesen. Ich brauche nur einen einfachen Weg, um darauf zuzugreifen. Ist das möglich?
namespace MyNamespace
{
public static class Config
{
public string Username => Configuration["Username"];
public string Password => Configuration["Password"];
}
}
Überall sonst in der App:
string username = Config.Username;
string password = Config.Password;
asp.net-core-mvc
Birdus
quelle
quelle
Antworten:
Eine etwas kürzere Version nach dem gleichen Prinzip wie oben ...
public Startup(IConfiguration configuration) { Configuration = configuration; StaticConfig = configuration; } public static IConfiguration StaticConfig { get; private set; }
So verwenden Sie es in einer anderen statischen Klasse:
string connString = Startup.StaticConfig.GetConnectionString("DefaultConnection");
quelle
private setter
, wie können Sie diese ersetzen? Sie müssen espublic
nur zum Testen machen, was nicht richtig ist.MyConfigObject.MyProperty = 5
einfach in Ihrem Test-Setup einstellen und in Bewegung bleiben.Nach langem Suchen funktioniert dies (in ASPNetCore 2.2) für den Zugriff auf die Konfiguration appsettings.json aus einer statischen Klasse, aber aus irgendeinem Grund wird appsettings.development.json nicht mehr richtig geladen, aber es könnte etwas anderes in meinem Projekt sein, das das durcheinander bringt. Der reloadOnChange funktioniert. Als Bonus gibt es auch IHostingEnvironment und IHttpContextAccessor. Während dies funktioniert, habe ich mich kürzlich entschlossen, wieder auf einen DI-Ansatz umzusteigen, um dem Paradigmenwechsel zu folgen, wie andere erwähnt haben.
Hier ist eine von vielen Möglichkeiten, auf DI-Inhalte (einschließlich der Konfiguration) in einer statischen Klasse zuzugreifen:
AppServicesHelper.cs:
public static class AppServicesHelper { static IServiceProvider services = null; /// <summary> /// Provides static access to the framework's services provider /// </summary> public static IServiceProvider Services { get { return services; } set { if (services != null) { throw new Exception("Can't set once a value has already been set."); } services = value; } } /// <summary> /// Provides static access to the current HttpContext /// </summary> public static HttpContext HttpContext_Current { get { IHttpContextAccessor httpContextAccessor = services.GetService(typeof(IHttpContextAccessor)) as IHttpContextAccessor; return httpContextAccessor?.HttpContext; } } public static IHostingEnvironment HostingEnvironment { get { return services.GetService(typeof(IHostingEnvironment)) as IHostingEnvironment; } } /// <summary> /// Configuration settings from appsetting.json. /// </summary> public static MyAppSettings Config { get { //This works to get file changes. var s = services.GetService(typeof(IOptionsMonitor<MyAppSettings>)) as IOptionsMonitor<MyAppSettings>; MyAppSettings config = s.CurrentValue; return config; } } } }
Startup.cs:
public Startup(IHostingEnvironment env) { var builder = new ConfigurationBuilder() .SetBasePath(env.ContentRootPath) .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true) .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: true) .AddEnvironmentVariables(); Configuration = builder.Build(); } public void ConfigureServices(IServiceCollection services) { //... services.AddHttpContextAccessor();//For HttpContext. // Register the IOptions object services.Configure<MyAppSettings>(Configuration.GetSection(nameof(MyAppSettings))); //Explicitly register the settings object by delegating to the IOptions object so that it can be accessed globally via AppServicesHelper. services.AddSingleton(resolver => resolver.GetRequiredService<IOptionsMonitor<MyAppSettings>>().CurrentValue); } public void Configure(IApplicationBuilder app, IHostingEnvironment env) { //... AppServicesHelper.Services = app.ApplicationServices; //... }
Regler:
public class MyController: Controller { public MyController() { } public MyAppSettings Config => AppServicesHelper.Config; public async Task<IActionResult> doSomething() { testModel tm = await myService.GetModel(Config.Setting_1); return View(tm); } }
Eine andere Klassenbibliothek:
public static class MyLibraryClass { public static string GetMySetting_ => AppServicesHelper.Config.Setting_1; public static bool IsDev => AppServicesHelper.HostingEnvironment.IsDevelopment(); }
MyAppSettings.cs ist eine Klasse, die einem MyAppSettings-Abschnitt in appsettings.json zugeordnet ist:
public class MyAppSettings { public string Setting_1 {get;set;} }
appsettings.json:
quelle
Ich stimme mcbowes zu, es steht in den Dokumenten , aber das erste Beispiel sieht eher so aus, wie Sie es brauchen ... wollen:
public class Program { public static IConfigurationRoot Configuration { get; set; } public static void Main(string[] args = null) { var builder = new ConfigurationBuilder() .SetBasePath(Directory.GetCurrentDirectory()) .AddJsonFile("appsettings.json"); Configuration = builder.Build(); Console.WriteLine($"option1 = {Configuration["option1"]}"); // Edit: IServiceCollection services = new ServiceCollection(); services.AddOptions(); services.Configure<HelloWorldOptions>(_configuration.GetSection("HelloWorld")); // And so on... } }
quelle
Configuration
von einer anderen internen statischen Klasse auf diese Instanz zugreifen, ohne sie jedes Mal neu erstellen zu müssen?Options
Muster verwenden .Vermeiden Sie die Verwendung einer statischen Klasse und verwenden Sie DI
namespace MyNamespace { public interface IConfig { string Username { get; } string Password { get; } } public class Config : IConfig { public Config(IConfiguration configuration) { _configuration = configuration; } readonly IConfiguration _configuration; public string Username => _configuration["Username"]; public string Password => _configuration["Password"]; } }
Das Setup DI in der StartUp-Klasse
public class Startup { public void ConfigureServices(IServiceCollection services) { //... services.AddTransient<IConfig, Config>(); ... } }
Und benutze es so
public class TestUsage { public TestUsage(IConfig config) { _config = config; } readonly IConfig _config; public string Username => _config.Username; public string Password => _config.Password; }
quelle
if(configuration["enabled"] == "True")
oderif(configuration.GetValue<int>("enabled"))
wenn ich das Gefühl habe, dass sieif(MyStaticClass.Enabled)
für Methoden, die mehrmals pro Sekunde aufgerufen werden, schneller und leichter ist.Sie können das Signleton- Muster verwenden, um von überall auf Ihre Konfigurationen zuzugreifen
public class ConnectionStrings { private ConnectionStrings() { } // property with getter only will not work. public static ConnectionStrings Instance { get; protected set; } = new ConnectionStrings(); public string DatabaseConnection { get; set; } }
und in Ihrer Startklasse
public class Startup { private readonly IConfiguration configuration; public Startup(IConfiguration configuration) { this.configuration = configuration; configuration.GetSection("ConnectionStrings").Bind(ConnectionStrings.Instance); } public void ConfigureServices(IServiceCollection services) { } public void Configure(IApplicationBuilder app) { } }
quelle
Dies wurde bereits gesagt, aber ich werde es sagen.
Ich glaube, .Net Core möchte, dass Entwickler Werte durch Dependency Inject erhalten. Dies ist mir aus meiner Forschung aufgefallen, aber ich spekuliere auch ein bisschen. Als Entwickler müssen wir diesem Paradigmenwechsel folgen, um .Net Core gut nutzen zu können.
Das Optionsmuster ist eine gute Alternative zur statischen Konfiguration. In Ihrem Fall sieht es so aus:
appsettings.json
SystemUser.cs
public class SystemUser { public string Username { get; set; } = ""; public string Password { get; set; } = ""; }
Startup.cs
Um die SystemUser-Klasse zu verwenden, gehen wir wie folgt vor.
TestController.cs
public class TestController : Controller { private readonly SystemUser systemUser; public TestController(IOptionsMonitor<SystemUser> systemUserOptions) { this.systemUser = systemUserOptions.CurrentValue; } public void SomeMethod() { var username = this.systemUser.Username; // "MyUsername" var password = this.systemUser.Password; // "Password1234" } }
Obwohl wir keine statische Klasse verwenden, denke ich, dass dies die beste Alternative ist, die Ihren Anforderungen entspricht. Andernfalls müssen Sie möglicherweise eine statische Eigenschaft innerhalb der Startup-Klasse verwenden, was imo eine beängstigende Lösung darstellt.
quelle
Wenn Sie Umgebungsvariablen als Konfiguration verwenden , können Sie direkt auf die Umgebungsvariable und nicht über das Konfigurationsobjekt zugreifen.
using System; namespace My.Example { public static class GetPaths { private static readonly string MyPATH = Environment.GetEnvironmentVariable("PATH"); private static readonly string MySpecialPath = Environment.GetEnvironmentVariable("PREFIX_SpecialPath"); ... } }
quelle
Persönlich mag ich die in diesem Link verwendete Methode
Im Wesentlichen wird Ihrer Optionsklasse lediglich ein statisches Feld hinzugefügt.
Dann können Sie in jeder statischen Klasse Folgendes tun:
Einfach und sehr einfach
quelle
Ich denke, Sie könnten die Erweiterungsfunktion verwenden, so etwas
Dann an jedem Ort einfach IConfiguration injizieren und Erweiterungsmethode verwenden
quelle
Ich habe gerade unter Klasse erstellt:
und unter Code:
quelle
Hier finden Sie eine Möglichkeit, die Konfigurationswerte von einer NET.Core-Seite abzurufen, ohne diese statisch referenzieren zu müssen, sie aber dennoch an andere statische Funktionen übergeben zu können, die von der nicht statischen Klasse aufgerufen werden.
Fügen Sie oben in Ihrer nicht statischen Klasse Folgendes hinzu:
private readonly IConfiguration _configuration;
Bringen Sie dann in der Konstruktorfunktion die vorhandene Konfiguration als Eingabe in die Funktion ein:
IConfiguration configuration
Weisen Sie dann die Konfiguration Ihrer schreibgeschützten Variablen innerhalb der Konstruktorfunktion zu:
_configuration = configuration;
Hier ist ein Beispiel, wie es aussehen sollte:
Danach können Sie auf die Konfiguration in einer beliebigen Funktion in der Klasse verweisen, indem Sie auf _configuration verweisen, und diese dann auch an andere statische Funktionen weitergeben, die Sie von anderen Klassen aufrufen:
Dann kann ich in der aufgerufenen statischen Klasse die Konfigurationswerte verwenden:
Ich habe eine Klasse, die einige gespeicherte Prozeduren zum Anzeigen und Ändern von Daten aufruft und Parameterwerte aus appsettings.json mit diesem Ansatz übergibt.
quelle
Beachten Sie die Anweisungen unter Verwendung von hier für ASP.NET - Core - Konfiguration.
Sie können eine Klasse erstellen, um Ihre Konfigurationseinstellungen zu speichern und dann auf die Werte zuzugreifen.
Im Start - ConfigureServices:
Dann injizieren Sie einfach Ihr Objekt, wo immer Sie es brauchen:
quelle
static class
Die IConfiguration kann an einer beliebigen Stelle im Projekt injiziert werden. Aber im Fall der statischen Klasse die Option, die ich verwende und vielleicht nur annähern ...
var Configuration = new ConfigurationBuilder() .AddUserSecrets<Startup>() .Build();
Und Sie können den erforderlichen Abschnitt hinzufügen, wie in diesem Codeblock oben, habe ich 'UserSecrets' hinzugefügt.quelle