首页 > 解决方案 > .Net Core 如何在应用程序中的任何位置访问配置

问题描述

我已经阅读了有关在 .Net Core 2.1 中设置和访问配置的不同方法以及似乎推荐的选项模式的文档(https://docs.microsoft.com/en-us/aspnet/core/fundamentals /configuration/options?view=aspnetcore-2.1)。但是,我似乎无法得到我想要的工作:

我做了以下事情:

应用设置:

{
  "ConnectionStrings": {
    "DefaultConnStr": "Server=(localdb)\\MSSQLLocalDB;Database=_CHANGE_ME;Trusted_Connection=True;MultipleActiveResultSets=true;Integrated Security=true",
    "AW2012ConnStr": "Server=localhost;Database=AW2012;Trusted_Connection=True;MultipleActiveResultSets=true;Integrated Security=true"
  }
}

我的配置:

public class MyConfig
{
    public string AWConnStr { get; }
    public string DefaultConnStr { get; }
}

启动:

public class Startup
{

public IConfiguration _config { get; set; }

public Startup(IHostingEnvironment env)
{
     var builder = new ConfigurationBuilder()
                .SetBasePath(env.ContentRootPath)
                .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true);
     _config = builder.Build();

}

public void ConfigureServices(IServiceCollection services)
{
      services.AddOptions();

      //add config to services for dependency injection
      //services.AddTransient<IMyConfig, MyConfig>();
     //services.AddScoped<IMyConfig, MyConfig>();
     var section = _config.GetSection("ConnectionStrings");
     services.Configure<MyConfig>(section);
}

    private static void HandleGetData(IApplicationBuilder app)
    {
        //DataHelper dataHelper = new DataHelper(_dataHelper);
        var _dataHelper = app.ApplicationServices.GetService<DataHelper>();

        app.Run(async context =>
        {
            //await context.Response.WriteAsync("<b>Get Data</b>");
            //await context.Response.WriteAsync(dataHelper.GetCompetitions(context.Request.QueryString.ToString()));
            await context.Response.WriteAsync(_dataHelper.GetCompetitions(context.Request.QueryString.ToString()));
        });
    }


  public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {

            app.Map("/Route1", HandleRoute1);

            app.Map("/Route2", HandleRoute2);

            app.Map("/GetData", HandleGetData);

            app.Run(async (context) =>
            {
                await context.Response.WriteAsync("Non Mapped Default");
            });
        }
 }

然后我想在我的代码中的任何地方访问任何类中的配置。因此,例如,我有以下课程,我只想阅读配置信息:

public interface IDataHelper
{
    string GetCompetitions(string val);
}

public class DataHelper : IDataHelper
{
    private readonly MyConfig _settings;

    public DataHelper(IOptions<MyConfig> options)
    {
        _settings = options.Value;
    }

    public string GetCompetitions( string queryStringVals)
    {

        return _settings.AWConnStr;

    } 
}

如上面在我的 Startup 类中所示,然后我想在我的启动中访问/调用 HandleGetData 函数中的某些内容,以便当我浏览到以下路线时: http://localhost:xxxxx/getdata我从Something返回响应.GetData 函数。

这个对吗?我遇到的问题是,当我创建Something 类的实例时,它要求我传入配置对象,但这并没有破坏注入它的目的。我应该如何设置它以类似于 DBContext 如何获取注入配置选项的上下文。services.AddTransient 和 services.AddScoped 之间有什么区别?我将两者都视为注册服务的一种方式。

标签: asp.net-coredependency-injection.net-core

解决方案


我想说的是,在 .Net Core 应用程序中,您不应该将实例传递IConfiguration给您的控制器或其他类。您应该改用通过注入的强类型设置IOtions<T>。将其应用于您的案例,修改 MyConfig 类(属性名称也应与配置中的名称匹配,因此您必须重命名配置(DefaultConnection->DefaultConnStr、AW2012ConnStr->AWConnStr 或属性,反之亦然):

public class MyConfig
{    
    public string AWConnStr { get; set; }
    public string DefaultConnStr { get; set; }
}

注册它:

public void ConfigureServices(IServiceCollection services)
{
    // in case config properties specified at root level of config file
    // services.Configure<MyConfig>(Configuration);

    // in case there are in some section (seems to be your case)
    var section = Configuration.GetSection("ConnectionStrings");
    services.Configure<MyConfig>(section);
}

将其注入所需的服务:

public class MyService
{
    private readonly MyConfig _settings;

    public MyService(IOptions<MyConfig> options)
    {
        _settings = options.Value;
    }
}

services.AddTransient 和 services.AddScoped 之间有什么区别?我将两者都视为注册服务的一种方式。

每次请求时都会创建瞬态生命周期服务。

每个请求创建一次作用域生命周期服务。


推荐阅读