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

LP1*_*P13 102 c# asp.net-core-mvc asp.net-core

我已经完成了ASP.NET核心的配置文档.文档说您可以从应用程序的任何位置访问配置.

下面是模板创建的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();
    }
}
Run Code Online (Sandbox Code Playgroud)

因此,在Startup.cs配置所有设置时,Startup.cs还有一个名为的属性Configuration

我无法理解您如何在控制器或应用程序中的任何位置访问此配置?MS建议使用选项模式,但我只有4-5个键值对,所以我不想使用选项模式.我只想访问应用程序中的Configuration.如何在任何课程中注入它?

Hen*_*ema 129

更新

使用ASP.NET Core 2.0将自动IConfiguration在依赖项注入容器中添加应用程序实例.这也适用于连同ConfigureAppConfigurationWebHostBuilder.

例如:

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

    host.Run();
}
Run Code Online (Sandbox Code Playgroud)

这与将IConfiguration实例作为单个对象添加到服务集合一样简单ConfigureServices:

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

   // ...
}
Run Code Online (Sandbox Code Playgroud)

ConfigurationStartup班上的实例在哪里?

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

public class HomeController
{
   public HomeController(IConfiguration configuration)
   {
      // Use IConfiguration instance
   }
}
Run Code Online (Sandbox Code Playgroud)

  • Mollerna ....如果你想在解决方案中的单独的类库项目中注入配置怎么样?尝试像这样的私有静态IConfiguration _configuration {get; 组; public DatabaseHelpers(IConfiguration configuration){_ configuration = configuration; 但_configuration始终为null ...它永远不会在contstructor中被命中 (4认同)
  • 也就是说,像这样传递 `IConfiguration` 是非常有漏洞的。使用 [选项模式](https://docs.microsoft.com/en-us/aspnet/core/fundamentals/configuration/options) 更好。 (4认同)
  • 如何直接在自定义类中访问"appsettings.json"中的值?没有从控制器传递数据?可能吗? (4认同)
  • @HenkMollema问题是如何注入* any *类……而不是如何注入“通过依赖注入解决的任何类”。我认为那是沟通不畅的地方...可能不会从以Controller或通过自动DI流程自动解决的其他对象开始的链中调用他的类。 (3认同)
  • @HenkMollema你能在这里添加一个例子吗?我如何将它注入任何类(从哪里?). (2认同)
  • @HenkMollema 我现在这样使用它:/sf/answers/3631174781/ (2认同)

kon*_*nzo 24

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

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

internal static IConfiguration Configuration { get; private set; }
Run Code Online (Sandbox Code Playgroud)

这使得配置可以在任何地方使用Startup.Configuration.GetSection...What can go wrong?

  • 这是迄今为止最简单的一种。 (5认同)
  • 在.Net6中他们删除了启动功能。不知道在哪里注射。 (3认同)

Sco*_*ttC 22

我知道这是旧的,但考虑到IOptions模式实现起来相对简单:

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

    public class ApplicationSettings
    {
        public string UrlBasePath { get; set; }
    }
    
    Run Code Online (Sandbox Code Playgroud)
  2. 注册您的设置

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

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

我不确定你为什么不这样做.

  • 仅供参考:https://docs.microsoft.com/en-us/aspnet/core/fundamentals/configuration/options?view=aspnetcore-2.1 (2认同)
  • 如何直接在自定义类中从“ appsettings.json”访问值? (2认同)
  • @JedatKinports你需要添加Nuget依赖项`Microsoft.Extensions.Configuration`,`Microsoft.Extensions.Configuration.Binder`和`Microsoft.Extensions.Configuration.Json`然后加载`appsettings.json`文件,如`var config =新的ConfigurationBuilder().AddJsonFile("appsettings.json").Build();`..还要确保`appsettings.json`复制到输出目录设置为`copy always` (2认同)

May*_*zer 17

正确的方法:

在.NET Core中,您可以将IConfigurationas作为参数注入到Class构造函数中,并且它将可用。

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

现在,当您要创建类的实例时,由于您的类正在注入IConfiguration,您将无法执行操作new MyClass(),因为您需要将IConfiguration参数传递给构造函数,因此,您需要注入您的注入链的类,这意味着两个简单的步骤:

1)将您的Classes添加IConfigurationIServiceCollection中的ConfigureServices()方法中Startup.cs

services.AddTransient<MyClass>();
Run Code Online (Sandbox Code Playgroud)

2)定义一个实例-假设在中Controller,然后使用构造函数将其注入:

public class MyController : ControllerBase
{
    private MyClass _myClass;
    public MyController(MyClass myClass)
    {
        _myClass = myClass;
    }
Run Code Online (Sandbox Code Playgroud)

现在您应该可以_myClass.configuration自由地享受自己的生活了...

另外一个选项:

如果您仍在寻找一种无需将类注入控制器即可使用的方法,则可以将其存储在中static class,将在中进行配置Startup.cs,例如:

public static class MyAppData
{
    public static IConfiguration Configuration;
}
Run Code Online (Sandbox Code Playgroud)

您的Startup构造函数应如下所示:

public Startup(IConfiguration configuration)
{
    Configuration = configuration;
    MyAppData.Configuration = configuration;
}
Run Code Online (Sandbox Code Playgroud)

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

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

  • 所有这些注入的配置文件似乎都是毫无意义的。TY为静态配置类的想法。 (4认同)
  • 当然,问题是关于访问任何类中的配置,而不仅仅是控制器。虽然随着精益服务(微服务)的新发展,可以想到这一点,但当涉及到迁移时,这是一个巨大的痛苦。这就是为什么微软让 CORE 的“System.Configuration”重回正轨的原因。现在,您可以像以前一样访问您的旧 app.configs。我这里说的不是控制器。我们正在谈论有自己的配置的组件 (2认同)
  • 这两种方法都有效,而且在我看来,支持或反对每种方法的论点都是学术性的。我已经将两者用于不同的应用程序......现在,感谢您极其简单的第二个选择。使用 DI 创建静态类相当困难。 (2认同)

小智 10

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

Run Code Online (Sandbox Code Playgroud)
  1. 我的类是一个 API 控制器,所以首先我添加了 using 引用,然后注入了 IConfiguration 接口
using Microsoft.Extensions.Configuration;

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

  • 我们需要访问它的类库,这是一个单独的项目。这是控制器。 (2认同)

Tad*_*dej 9

我现在是这样做的:

// 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;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

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

var appSettingsJson = AppSettingsJson.GetAppSettings();
// appSettingsJson["keyName"]
Run Code Online (Sandbox Code Playgroud)

  • 终于有一些可以在静态方法中工作而不依赖于注入器疯狂的东西了。矛盾的独立终于来了!;-)...但是太多 NuGet 包依赖项了啊! (2认同)
  • 值得一提的是,将 Microsoft.Extensions.Configuration 和 Microsoft.Extensions.Configuration.Json 添加到该代码工作中。 (2认同)

pur*_*ang 5

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

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;
    }
...
}
Run Code Online (Sandbox Code Playgroud)

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

例子:

public class MyClass{

    private Iconfiguration _config;

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

    ... // access _config["myAppSetting"] anywhere in this class
}
Run Code Online (Sandbox Code Playgroud)