我如何访问配置在任何类在ASP.净的核心

本文关键字:任何类 ASP 核心 配置 何访问 访问 | 更新日期: 2023-09-27 18:04:50

我已经阅读了ASP的配置文档。净的核心。文档说你可以从应用程序的任何地方访问配置。

下面是模板

创建的Startup.cs
public class Startup
{
    public Startup(IHostingEnvironment env)
    {
        var builder = new ConfigurationBuilder()
            .SetBasePath(env.ContentRootPath)
            .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
            .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true);
        if (env.IsEnvironment("Development"))
        {
            // This will push telemetry data through Application Insights pipeline faster, allowing you to view results immediately.
            builder.AddApplicationInsightsSettings(developerMode: true);
        }
        builder.AddEnvironmentVariables();
        Configuration = builder.Build();
    }
    public IConfigurationRoot Configuration { get; }
    // This method gets called by the runtime. Use this method to add services to the container
    public void ConfigureServices(IServiceCollection services)
    {
        // Add framework services.
        services.AddApplicationInsightsTelemetry(Configuration);
        services.AddMvc();
    }
    // This method gets called by the runtime. Use this method to configure the HTTP request pipeline
    public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
    {
        loggerFactory.AddConsole(Configuration.GetSection("Logging"));
        loggerFactory.AddDebug();
        app.UseApplicationInsightsRequestTelemetry();
        app.UseApplicationInsightsExceptionTelemetry();
        app.UseMvc();
    }
}

Startup.cs中我们配置了所有的设置,startup。cs也有一个名为Configuration的属性

我不明白的是你如何在控制器或应用程序中的任何地方访问这个配置?MS建议使用选项模式,但我只有4-5个键值对,所以我不想使用选项模式。我只是想在应用程序中访问配置。我如何将它注入到任何类中?

我如何访问配置在任何类在ASP.净的核心

更新

使用ASP。. NET Core 2.0将自动在依赖注入容器中添加应用程序的IConfiguration实例。这也可以与WebHostBuilder上的ConfigureAppConfiguration一起使用。

例如:

public static void Main(string[] args)
{
    var host = WebHost.CreateDefaultBuilder(args)
        .ConfigureAppConfiguration(builder =>
        {
            builder.AddIniFile("foo.ini");
        })
        .UseStartup<Startup>()
        .Build();
    host.Run();
}

就像在ConfigureServices中将IConfiguration实例作为单例对象添加到服务集合中一样简单:

public void ConfigureServices(IServiceCollection services)
{
   services.AddSingleton<IConfiguration>(Configuration);
   // ...
}

其中ConfigurationStartup类中的实例。

这允许你在任何控制器或服务中注入IConfiguration:

public class HomeController
{
   public HomeController(IConfiguration configuration)
   {
      // Use IConfiguration instance
   }
}

正确的做法。"依赖Injection"

在。net Core中,你可以将IConfiguration作为参数注入到你的Class构造函数中,它将可用。

public class MyClass 
{
    private IConfiguration configuration;
    public MyClass(IConfiguration configuration)
    {
        ConnectionString = new configuration.GetValue<string>("ConnectionString");
    }

现在,当你想创建类的实例时,因为你的类被注入了IConfiguration,你不能只做new MyClass(),因为它需要一个IConfiguration参数注入到构造函数中,所以,你需要把你的类也注入到注入链中,这意味着两个简单的步骤:

  1. Startup.cs

    ConfigureServices()方法中添加您的类/es -您想使用IConfiguration的地方到IServiceCollection

    services.AddTransient ();

  2. 定义一个实例——比如在Controller中,并使用构造函数注入它:

    公共类MyController: ControllerBase{private MyClass _myClass;MyController(MyClass MyClass){_myClass = myClass;}

现在你应该可以自由地享受你的_myClass.configuration

另一个选项,静态属性:

如果您仍在寻找一种方法,使其可用,而不必注入类到控制器中,那么您可以将其存储在static class中,您将在Startup.cs中配置,如:

public static class MyAppData
{
    public static IConfiguration Configuration;
}

你的Startup构造函数应该是这样的:

public Startup(IConfiguration configuration)
{
    Configuration = configuration;
    MyAppData.Configuration = configuration;
}

然后在程序的任何地方使用MyAppData.Configuration

不要问我为什么第一种选择是正确的方式,我可以看到经验丰富的开发人员总是避免垃圾数据,并且很好地理解,在内存中一直有大量可用的数据并不是最佳实践,这对性能和开发都没有好处,也许只拥有你需要的东西也更安全。

我知道这是旧的,但考虑到IOptions模式相对容易实现:

  1. 带有公共get/set属性的类,与配置中的设置相匹配

    public class ApplicationSettings
    {
        public string UrlBasePath { get; set; }
    }
    
  2. 注册你的设置

    public void ConfigureServices(IServiceCollection services)
    {
     ...
     services.Configure<ApplicationSettings>(Configuration.GetSection("ApplicationSettings"));
    ...
    }
    
  3. 通过IOptions注入

    public class HomeController
    {
       public HomeController(IOptions<ApplicationSettings> appSettings)
       { ...
        appSettings.Value.UrlBasePath
        ...
        // or better practice create a readonly private reference
        }
     }
    

我不知道你为什么不这么做。

还有一个选项使configuration在startup.cs中是静态的,这样你就可以在任何地方轻松地访问它,静态变量很方便啊!

public Startup(IConfiguration configuration)
{
    Configuration = configuration;
}
internal static IConfiguration Configuration { get; private set; }

这使得配置可以访问任何地方使用Startup.Configuration.GetSection...什么可能出错?

我现在是这样做的:

// Requires NuGet package Microsoft.Extensions.Configuration.Json
using Microsoft.Extensions.Configuration;
using System.IO;
namespace ImagesToMssql.AppsettingsJson
{
    public static class AppSettingsJson
    {           
        public static IConfigurationRoot GetAppSettings()
        {
            string applicationExeDirectory = ApplicationExeDirectory();
            var builder = new ConfigurationBuilder()
            .SetBasePath(applicationExeDirectory)
            .AddJsonFile("appsettings.json");
            return builder.Build();
        }
        private static string ApplicationExeDirectory()
        {
            var location = System.Reflection.Assembly.GetExecutingAssembly().Location;
            var appRoot = Path.GetDirectoryName(location);
            return appRoot;
        }
    }
}

然后我在需要从应用设置中获取数据的地方使用这个。json文件:

var appSettingsJson = AppSettingsJson.GetAppSettings();
// appSettingsJson["keyName"]

我知道可能有几种方法可以做到这一点,我使用Core 3.1,正在寻找最佳/更干净的选项,我最终这样做:

  1. 我的启动类是默认的
public Startup(IConfiguration configuration)
{
    Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
    services.AddControllers();
}
我appsettings
  • 。json是这样的
  • {
      "CompanySettings": {
        "name": "Fake Co"
      }
    }
    
  • 我的类是一个API控制器,所以首先我添加了using引用,然后注入IConfiguration接口
  • using Microsoft.Extensions.Configuration;
    public class EmployeeController 
    {
        private IConfiguration _configuration;
        public EmployeeController(IConfiguration configuration)
        {
            _configuration = configuration;
        }
    }
    
    最后我使用了GetValue方法
    public async Task<IActionResult> Post([FromBody] EmployeeModel form)
    {
        var companyName = configuration.GetValue<string>("CompanySettings:name");
        // companyName = "Fake Co"
    }
    

    我查看了选项模式示例,看到如下:

    public class Startup
    {
        public Startup(IConfiguration config)
        {
            // Configuration from appsettings.json has already been loaded by
            // CreateDefaultBuilder on WebHost in Program.cs. Use DI to load
            // the configuration into the Configuration property.
            Configuration = config;
        }
    ...
    }
    

    当在类的构造函数中添加配置时,我可以通过DI访问配置选项。

    的例子:

    public class MyClass{
        private Iconfiguration _config;
        public MyClass(Iconfiguration config){
            _config = config;
        }
        ... // access _config["myAppSetting"] anywhere in this class
    }
    

    在2017年8月,微软发布了。net CORE v4.4的System.Configuration。目前v4.5和v4.6预览版。

    对于我们这些致力于从。net框架到CORE的转换的人来说,这是必不可少的。它允许保存和使用当前的app.config文件,这些文件可以从任何程序集访问。它甚至可能是appsettings.json的替代品,因为微软意识到了对它的需求。在FW中和以前一样。有一个区别:

    在web应用程序中,[例如ASP。. NET CORE WEB API]你需要使用app.config而不是 WEB。配置您的appSettingsconfigurationSection。您可能需要使用web.config,但只有当您通过IIS部署您的网站。您将iis特定的设置放入web.config

    我已经用netstandard20 DLL和Asp.net Core Web Api测试了它,它都在工作。

    在ASP中使用选项模式. NET Core是要走的路。我只是想补充一点,如果你需要访问startup.cs中的选项,我建议这样做:

    CosmosDbOptions.cs:

    public class CosmosDbOptions
    {
        public string ConnectionString { get; set; }
    }
    

    Startup.cs:

    public void ConfigureServices(IServiceCollection services)
    {
        // This is how you can access the Connection String:
        var connectionString = Configuration.GetSection(nameof(CosmosDbOptions))[nameof(CosmosDbOptions.ConnectionString)];
    }
    

    我必须在启动时读取自己的参数。
    在 WebHost启动之前,必须有(因为我需要从参数文件中"监听"url/IP和端口,并将其应用于WebHost)。此外,我需要在整个应用程序中设置public

    经过一段时间的搜索(没有找到完整的示例,只有片段)和各种尝试和错误之后,我决定用自己的.ini文件做"旧方法"。
    所以. .

    如果你想使用你自己的。ini文件和/或设置"监听url/IP"你自己和/或需要公开的设置,这是给你的…

    完整的示例,适用于core 2.1 (mvc):

    创建一个在ini文件——例如:


    (启动)URL = http://172.16.1.201:22222
    (参数)
    * Dummy1 = gew7623
    Dummy1 = true
    Dummy2 = 1

    Dummyx仅作为字符串以外的其他日期类型的示例(也用于测试"错误参数"的情况(见下面的代码)。

    在项目的根目录中添加了一个代码文件,用于存储全局变量:

    namespace MatrixGuide
    {
        public static class GV
        {
            // In this class all gobals are defined
            static string _cURL;
            public static string cURL // URL (IP + Port) on that the application has to listen
            {
                get { return _cURL; }
                set { _cURL = value; }
            }
            static bool _bdummy1;
            public static bool bdummy1 // 
            {
                get { return _bdummy1; }
                set { _bdummy1 = value; }
            }
            static int _idummy1;
            public static int idummy1 // 
            {
                get { return _idummy1; }
                set { _idummy1 = value; }
            }
            static bool _bFehler_Ini;
            public static bool bFehler_Ini // 
            {
                get { return _bFehler_Ini; }
                set { _bFehler_Ini = value; }
            }
            // add further  GV variables here..
        }
        // Add further classes here... 
    }
    

    更改program.cs中的代码(在CreateWebHostBuilder()之前):

    namespace MatrixGuide
    {
        public class Program
        {
            public static void Main(string[] args)
            {
                // Read .ini file and overtake the contend in globale
                // Do it in an try-catch to be able to react to errors
                GV.bFehler_Ini = false;
                try
                {
                    var iniconfig = new ConfigurationBuilder()
                    .SetBasePath(Directory.GetCurrentDirectory())
                    .AddIniFile("matrixGuide.ini", optional: false, reloadOnChange: true)
                    .Build();
                    string cURL = iniconfig.GetValue<string>("Startup:URL");
                    bool bdummy1 = iniconfig.GetValue<bool>("Parameter:Dummy1");
                    int idummy2 = iniconfig.GetValue<int>("Parameter:Dummy2");
                    //
                    GV.cURL = cURL;
                    GV.bdummy1 = bdummy1;
                    GV.idummy1 = idummy2;
                }
                catch (Exception e)
                {
                    GV.bFehler_Ini = true;
                    Console.ForegroundColor = ConsoleColor.Red;
                    Console.WriteLine("!! Fehler beim Lesen von MatrixGuide.ini !!");
                    Console.WriteLine("Message:" + e.Message);
                    if (!(e.InnerException != null))
                    {
                        Console.WriteLine("InnerException: " + e.InnerException.ToString());
                    }
                    Console.ForegroundColor = ConsoleColor.White;
                }
                // End .ini file processing
                //
                CreateWebHostBuilder(args).Build().Run();
            }
            public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
                WebHost.CreateDefaultBuilder(args)
                .UseStartup<Startup>() //;
                .UseUrls(GV.cURL, "http://localhost:5000"); // set the to use URL from .ini -> no impact to IISExpress
        }
    }
    

    这样:

    • 我的应用程序配置与应用程序设置分开。json和I如果MS在未来的版本中做了更改,没有副作用需要担心;-)
    • 我有我的设置全局变量
    • 我能够为每个设备设置"监听url",应用程序运行在(我的开发机器,内网服务器和internet服务器)
    • 我可以停用设置,旧的方式(只需设置一个*之前)
    • 我能够反应,如果有什么是错误的。ini文件(例如类型不匹配)
      如果-例如-设置了错误的类型(例如激活*Dummy1=gew7623而不是当Dummy1=true时,主机在控制台上显示红色信息(包括例外)我也能在应用程序(全球之声。bFehler_Ini ist设置为true,如果有错误. ini)