.Net Core如何在应用程序中随处访问配置

问题描述 投票:1回答:2

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

我做了以下事情:

的AppSettings:

{
  "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"
  }
}

的myconfig:

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-core dependency-injection .net-core
2个回答
3
投票

我会说在.Net Core应用程序中,你不应该将IConfiguration的实例传递给你的控制器或其他类。您应该使用通过IOtions<T>注入的强类型设置。将它应用到您的案例中,修改MyConfig类(属性名称也应与config中的名称匹配,因此您必须重命名config(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之间有什么区别?我已经看到两者都是注册服务的方式。

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

每个请求创建一次范围生命周期服务。


0
投票

你必须为Something做同样的事情,就像你为MyConfig做的那样:

public interface ISomething
{
    string GetSomeData();
}

然后:

public class Something : ISomething
{
    public IConfiguration _config { get; set; }

    public Something(IConfiguration configuration)
    {
        _config = configuration;
    }

    public string GetSomeData()
    {
        return _config["DefaultConnStr"];
    }
}

然后在ConfigureService类的Startup方法如下:

services.AddScoped<ISomething,Something>();

然后按如下方式调用GetSomeData()

public class CallerClass
{
     public ISomething _something { get; set; }

     public CallerClass(ISomething something)
     {
            _something = something;
     }

     public string CallerMethod()
     {
         return _something.GetSomeData();
     }
}

然后:

services.AddTransient和services.AddScoped之间有什么区别?我已经看到两者都是注册服务的方式。

以下是来自microsoft的详细信息:

Service Lifetime details in ASP.NET Core

© www.soinside.com 2019 - 2024. All rights reserved.