如何在ASP.NET Core中的任何类中访问Configuration?

时间:2016-08-30 15:45:22

标签: c# asp.net-core asp.net-core-mvc

我在ASP.NET核心上经历了configuration documentation。文档说您可以从应用程序的任何位置访问配置。

以下是由模板

创建的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建议使用options pattern,但我只有4-5个键值对,所以我不想使用选项模式。我只想访问应用程序中的Configuration。我如何在任何课程中注入它?

11 个答案:

答案 0 :(得分:113)

更新

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

例如:

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

    host.Run();
}

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

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

   // ...
}

Configuration类中Startup的实例。

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

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

答案 1 :(得分:20)

我知道这已经过时了,但考虑到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
        }
     }
    
  4. 我不确定你为什么不这样做。

答案 2 :(得分:6)

  

正确的方法:

在.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)在IConfiguration的{​​{1}}方法中,将您要使用IServiceCollection的类添加到ConfigureServices()

Startup.cs

2)定义一个实例-在services.AddTransient<MyClass>(); 中说,然后使用构造函数将其注入:

Controller

现在,您应该可以自由享受public class MyController : ControllerBase { private MyClass _myClass; public 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; }

不要直面我为什么第一个选择是正确的方法,我可以看到有经验的开发人员始终避免使用垃圾数据,并且众所周知,拥有大量可用数据不是最佳实践一直存储在内存中,对性能和开发都没有好处,也许只有您需要的东西才更安全。

答案 3 :(得分:3)

我查看了选项模式示例并看到了:

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;
    }
...
}

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

示例:

public class MyClass{

    private Iconfiguration _config;

    public MyClass(Iconfiguration config){
        _config = config;
    }

    ... // access _config["myAppSetting"] anywhere in this class
}

答案 4 :(得分:3)

我知道可能有几种方法可以做到这一点,我使用的是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();
}
  1. 我的appsettings.json就是这样
{
  "CompanySettings": {
    "name": "Fake Co"
  }
}

  1. 我的课程是API控制器,因此我首先添加了using引用,然后注入了IConfiguration接口
using Microsoft.Extensions.Configuration;

public class EmployeeController 
{
    private IConfiguration _configuration;
    public EmployeeController(IConfiguration configuration)
    {
        _configuration = configuration;
    }
}
  1. 最后我使用了GetValue方法
public async Task<IActionResult> Post([FromBody] EmployeeModel form)
{
    var companyName = configuration.GetValue<string>("CompanySettings:name");
    // companyName = "Fake Co"
}

答案 5 :(得分:2)

我现在正在这样做:

// 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;
        }
    }
}

然后在需要从appsettings.json文件获取数据的地方使用它:

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

答案 6 :(得分:2)

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

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

internal static IConfiguration Configuration { get; private set; }

这使使用Startup.Configuration.GetSection...的任何地方都可以访问配置。

答案 7 :(得分:0)

2017年8月8日,Microsoft推出了System.Configuration for .NET CORE v4.4。 imports files that no longer exist和v4.6预览。

对于那些致力于从.Net Framework到CORE转换的人们来说,这是必不可少的。它允许保留和使用当前的app.config文件,可以从任何程序集中进行访问。由于Microsoft意识到了对appsettings.json的需求,因此它甚至可以替代app.config。与以前的固件相同。有一个区别:

在网络应用程序中,[例如您需要为appSettingsconfigurationSection使用web.config not web.config来使用ASP.NET CORE WEB API。您可能需要使用web.config,但仅在通过IIS部署站点时才需要。您将IIS特定的设置放入{{1}}

我已经使用 netstandard20 DLL和 Asp.net Core Web Api 对它进行了测试,并且一切正常。

答案 8 :(得分:0)

使用Options pattern in 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)];
}

答案 9 :(得分:0)

在ASP.NET Core中,有一些配置提供程序可以从几乎任何地方(例如文件)读取配置。 JSON,INI或XML,环境变量,Azure密钥保险库,命令行参数等,以及更多其他来源。我已经写过a step by step guide,向您展示了如何在各种文件(如JSON,INI或XML)中配置应用程序设置,以及如何从应用程序代码中读取这些设置。我还将演示如何将应用程序设置读取为自定义.NET类型(类),以及如何使用内置的ASP.NET Core依赖项注入来读取解决方案中可用的多个类,服务甚至项目中的配置设置

阅读A Step by Step Guide for ASP.NET Core Configuration

答案 10 :(得分:-2)

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

搜索了一会儿(找不到完整的示例,仅显示摘录),并且经过反复尝试,我决定使用自己的.ini文件以“旧方法”进行操作。
所以..如果您想使用自己的.ini文件和/或自己设置“侦听url / IP”和/或需要公共设置,这是给您的... < / p>

完整示例,对核心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

    }
}

这种方式:

  • 我的应用程序配置与appsettings.json分开,我 如果MS在将来的版本中进行了更改,则无需担心;-)
  • 我在全局变量中有设置
  • 我能够为运行applicaton的每台设备(我的开发机,Intranet服务器和Internet服务器)设置“侦听url”
  • 我可以停用设置的旧方法(只需在之前设置*)
  • 如果.ini文件有问题(例如,类型不匹配),我可以做出反应
    如果-例如-设置了错误的类型(例如* Dummy1 = gew7623已激活,而不是 (Dummy1 = true)主机在控制台上显示红色信息 (包括例外),我也可以在 应用程序(GV.bFehler_Ini ist设置为true,如果存在错误 .ini)