ASP.NET Core 6 как получить доступ к конфигурации во время установки
В более ранних версиях у нас был класс Startup.cs, и мы получали объект конфигурации, как показано ниже, в файле запуска.
public class Startup
{
private readonly IHostEnvironment environment;
private readonly IConfiguration config;
public Startup(IConfiguration configuration, IHostEnvironment environment)
{
this.config = configuration;
this.environment = environment;
}
public void ConfigureServices(IServiceCollection services)
{ ... }
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{ ... }
}
Теперь в .NET 6 (с Visual Studio 2022) мы не видим класс Startup.cs, он полностью удален. Итак, как нам получить эти объекты, такие как Configuration (IConfiguration) и Hosting Environment (IHostEnvironment)
Как нам получить эти объекты, скажем, прочитать конфигурацию из appsettngs? В настоящее время файл Program.cs выглядит так.
using Festify.Database;
using Microsoft.EntityFrameworkCore;
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddRazorPages();
builder.Services.AddDbContext<FestifyContext>();
////////////////////////////////////////////////
// The following is Giving me error as Configuration
// object is not avaible, I dont know how to inject this here.
////////////////////////////////////////////////
builder.Services.AddDbContext<FestifyContext>(opt =>
opt.UseSqlServer(
Configuration.GetConnectionString("Festify")));
var app = builder.Build();
// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthorization();
app.MapRazorPages();
app.Run();
Я хочу прочитать конфигурацию из файла appsettings.
12 ответов
WebApplicationBuilder
вернулся
WebApplication.CreateBuilder(args)
разоблачает а также характеристики:
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
...
ConfigurationManager configuration = builder.Configuration;
IWebHostEnvironment environment = builder.Environment;
WebApplication
вернулся
WebApplicationBuilder.Build()
также обнажает
Configuration
а также
Environment
:
var app = builder.Build();
IConfiguration configuration = app.Configuration;
IWebHostEnvironment environment = app.Environment;
Также ознакомьтесь с по руководствоммиграции и примерами кода .
В
Program.cs
, создается WebApplicationBuilder, как показано ниже.
var builder = WebApplication.CreateBuilder(args);
Как только мы создадим билдер, конфигурация будет доступна.
Предположим, у вас есть значение по умолчанию. Приведенный ниже пример кода вернет настройку уровня журнала конфигурации по умолчанию из файла конфигурации JSON.
builder.Configuration["Logging:LogLevel:Default"] // returns "Warning"
После запуска приложения вы можете получить доступ к параметрам конфигурации с помощью внедрения зависимостей в другие классы вашего приложения.
public MyClass(IConfiguration configuration)
{
var logLevel = configuration["Logging:LogLevel:Default"];
}
Хорошая функция, которую стоит рассмотреть, чтобы создать класс, который представляет ваши настройки, а затем привязать конфигурацию к экземпляру этого типа класса. Например, предположим, что вы создаете новый класс с именем
MyAppSettings
с той же структурой, что и ваша
appSettings.json
, вы можете сделать следующее:
var myAppSettings = builder.Configuration.Get<MyAppSettings>();
string logLevel = myAppSettings.Logging.LogLevel.Default;
.NET 6 уже предоставляет объект Builder в Program.cs
var builder = WebApplication.CreateBuilder(args);
Просто используйте этот построитель для доступа к конфигурации и среде в качестве примера, чтобы получить ConnectionString из app.settings.cs следующим образом:
builder.Services.AddDbContext<DataContext>( options =>
{
options.UseSqlServer(builder.Configuration.GetConnectionString("DefaultConnectiion"));
});
Я знаю, что вопрос изначально задаетASPNetCore
но если вам случится сделать то же самое для рабочей службы и приземлиться здесь, как я, надеюсь, этот ответ поможет вам.
Пользователь рабочей службыIHostBuilder
вместоIWebApplicationBuilder
и это не предоставляет свойство Configuration, но вы можете принять экземпляр IHostBuilderContext в метод ConfigureServices, который предоставляет экземпляр Configuration.
IHost host = Host.CreateDefaultBuilder(args)
.ConfigureServices((context, services) =>
{
var settings = context.Configuration.Get<Settings>();
})
.Build();
//.NET6 Program.cs -(для получения свойств конфигурации приложения)
var builder = WebApplication.CreateBuilder(args);
builder.Configuration.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true);
builder.Configuration.AddJsonFile($"appsettings.Dev.json", optional: true);
builder.Configuration.AddEnvironmentVariables();
// projectwide instances
public IConfiguration _configuration;
public AccountsAPIController(IConfiguration configuration)
{
_configuration = configuration;
}
// _configuration.GetConnectionString("DefaultConnection");
Это сработало для меня ---
// Read in from JSON file
builder.Services.Configure<ConnectionKeys>(builder.Configuration.GetSection("ConnectionKeys"));
Все, что вам нужно, это добавить «строитель». перед вашей конфигурацией
Нравиться:
builder.Services.AddDbContext<FestifyContext>(opt =>opt.UseSqlServer(builder.Configuration.GetConnectionString("Festify")));
Это немного отличается от предыдущих ответов, и я включаю это, так как просматривал что-то подобное.
В твоей
Program.cs
вы также можете сгруппировать код в методе и вызвать его, чтобы он меньше работал или группировал похожие вещи. Я не буду помещать весь код; не буду приводить полный список
using
директивы здесь, но достаточно, чтобы продемонстрировать технику, и я пропущу некоторый код метода. Этого недостаточно или даже, возможно, слишком много для вашего решения, и вам потребуется индивидуальная настройка.
using AutoMapper;
using MicroKnights.Log4NetHelper;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Authentication.OpenIdConnect;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.DataProtection;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc.Authorization;
using Microsoft.AspNetCore.Mvc.Infrastructure;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
...
//all your using directives
using StackExchange.Redis;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Claims;
using System.Threading.Tasks;
//a variable to hold configuration
IConfiguration Configuration;
var builder = WebApplication.CreateBuilder(args);
Configuration = builder.Configuration;
// call some methods
ConfigureAuth(builder.Services);
ConfigureRedis(builder.Services);
ConfigureSession(builder.Services);
ConfigureMvc(builder.Services);
ConfigureServices(builder.Services);
var app = builder.Build();
ConfigureMiddleWare(app);
app.Run();
// we are done with the main part, now the methods
void ConfigureMvc(IServiceCollection services)
{
builder.Services.AddMvc(config =>
{
var policy = new AuthorizationPolicyBuilder().RequireAuthenticatedUser().Build();
config.Filters.Add(new AuthorizeFilter(policy));
})
.AddRazorPagesOptions(options => { options.Conventions.AddPageRoute("/Home/Login", ""); })
.AddJsonOptions(options =>
{
options.JsonSerializerOptions.PropertyNameCaseInsensitive = true;
options.JsonSerializerOptions.PropertyNamingPolicy = null;
});
}
void ConfigureSession(IServiceCollection services)
{
builder.Services.AddSession(options =>
{
options.Cookie.Name = "mygreatsite_session";
options.IdleTimeout = TimeSpan.FromMinutes(60);
});
}
void ConfigureRedis(IServiceCollection services)
{
var redisConfig = new RedisOptions();
Configuration.GetSection(RedisOptions.RedisConfig).Bind(redisConfig);
services.AddStackExchangeRedisCache(options =>
{
options.Configuration = redisConfig.ConnectionString;
options.InstanceName = "mygreatsite_";
});
services.AddDataProtection()
.SetApplicationName("MyGreatSite.Website")
.PersistKeysToStackExchangeRedis(ConnectionMultiplexer.Connect(redisConfig.ConnectionString), "DataProtection-Keys");
}
void ConfigureMiddleWare(WebApplication app)
{
if (builder.Environment.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseBrowserLink();
}
else
{
app.UseExceptionHandler("/Home/Error");
}
app.UseRouting();
app.UseCors("default");
app.UseCookiePolicy();
app.UseAuthentication();
app.UseAuthorization();
app.UseSession();
app.UseEndpoints(endpoints =>
{
endpoints.MapDefaultControllerRoute().RequireAuthorization();
endpoints.MapControllerRoute(
name: "Default",
pattern: "{controller=Home}/{action=Login}"
);
});
}
У меня работали следующие коды:
Программа.cs:
var builder = WebApplication.CreateBuilder(args);
string connString = builder.Configuration.GetConnectionString("conStr");
ConnectionString = connString;
...
partial class Program
{
public static string? ConnectionString { get; private set; }
}
calling class:
string cnStr = Program.ConnectionString;
Если вы определили токен в файле appsetting.json, вы можете определить этот токен json в программе cs следующим образом:
appsettting.json:
"AppSettings": {
"Token": "token"
},
программа cs:
var key = Encoding.ASCII.GetBytes(builder.Configuration.GetSection("Appsettings:Token").Value);
Альтернатива: действительно ли мне нужен DI, когда дело доходит до настроек?
Особенно, когда мне нужны эти настройки из переменных среды, что часто бывает в контейнерных средах, и, возможно, чтобы избежать утечки секретов в файлах json.
Тогда просто создайте статический класс, например:
public static class SettingsService
{
private static Settings _settings = null;
public static Settings Settings
{
get
{
if (_settings == null)
{
_settings = new Settings()
{
hostmail = Environment.GetEnvironmentVariable("hostmail") ?? "",
hostmailuser = Environment.GetEnvironmentVariable("hostmailuser") ?? "",
hostmailpass = Environment.GetEnvironmentVariable("hostmailpass") ?? "",
hostmailport = int.Parse(Environment.GetEnvironmentVariable("hostmailport") ?? "993"),
LogLevel = Enum.Parse<LogLevel>(Environment.GetEnvironmentVariable("LogLevel") ?? "Information"),
natsurl = Environment.GetEnvironmentVariable("natsurl") ?? "nats://localhost:4200",
natsnkeypubkey = Environment.GetEnvironmentVariable("natsnkeypubkey") ?? "",
natsnkeypath = Environment.GetEnvironmentVariable("natsnkeypath") ?? "",
roles = (Environment.GetEnvironmentVariable("roles") ?? "").Split(';'),
poolsize = int.Parse(Environment.GetEnvironmentVariable("poolsize") ?? "10"),
tmpfolder = Environment.GetEnvironmentVariable("tmpfolder") ?? "temp",
fontsfolder = Environment.GetEnvironmentVariable("fontsfolder") ?? "fonts"
};
}
return _settings;
}
}
}
и файл program.cs типа:
var sets = SettingsService.Settings;
IHost host = Host.CreateDefaultBuilder(args).ConfigureAppSettings()
.ConfigureServices(services =>
{
if (sets.serverrole == "inboxsignaler")
{
services.AddHostedService<InboxSignaler>();
}
services.AddNats(options =>
{
options.Url = sets.natsurl;
options.SetNkey(sets.natsnkeypubkey, sets.natsnkeypath);
});
})
.Build();
await host.RunAsync();
мои 2 цента...
Я решил эту проблему простым способом:
В Program.cs:
using SomeAppName.Startup;
WebApplication.CreateBuilder(args)
.RegisterServices()
.Build()
.SetupMiddleware()
.Run();
Следующий:
public static WebApplicationBuilder RegisterServices(this WebApplicationBuilder builder)
{
BuildConfiguration(builder.Environment);
//// Any code
}
Окончательно:
private static IConfiguration BuildConfiguration(IHostEnvironment env)
{
var configurationBuilder = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("./Configuration/appsettings.json", optional: false, reloadOnChange: true)
.AddJsonFile("./Configuration/appsettings.other.json", optional: false, reloadOnChange: true)
.AddJsonFile($"./Configuration/appsettings.{env.EnvironmentName}.json", optional: true)
.AddJsonFile($"./Configuration/appsettings.other.{env.EnvironmentName}.json", optional: true)
.AddEnvironmentVariables();
Configuration = configurationBuilder.Build();
return Configuration;
}