.Net Core Как получить доступ к конфигурации в любом месте приложения - PullRequest
0 голосов
/ 16 сентября 2018

Я прочитал документацию по различным способам настройки и доступа к конфигурации в .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 вводит контекст с параметрами конфигурации. И в чем разница между службами. AddTransient и службами. AddScoped? Я видел как способ регистрации службы.

Ответы [ 2 ]

0 голосов
/ 16 сентября 2018

Я бы сказал, что в приложении .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;
    }
}

А в чем разница между службами. AddTransient и services.AddScoped? Я видел как способ регистрации службы.

Переходные сервисы продолжительности жизни создаются каждый раз, когда их запрашивают.

Scoped Сервисы продолжительности жизни создаются один раз для каждого запроса.

0 голосов
/ 16 сентября 2018

Вы должны сделать то же самое для 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();
     }
}

Тогда:

А в чем разница между службами. AddTransient и службами. AddScoped? Я видел как способ регистрации службы.

Вот подробности об этом от Microsoft:

Сведения о сроке службы в ASP.NET Core

...