Мы разрабатываем приложение ASP.Net Core MVC 2.
Наш специалист по настройке сказал мне, когда я настраивал проект, что мы не можем установить обычную системную переменную ASPNETCORE_ENVIRONMENT на наших боксах, потому что мы будем делиться с другими командами.
Итак, я начал искать способы ручного управления средой, в которой приложение ASP.Net Core MVC считает, что оно работает.
Я думал, что все готово и понял.
Это наша установка.
В моем файле appsettings.json у меня есть переменная настроек, которая называется "AARTS_ENVIRONMENT". (AARTS - название нашего проекта).
{
"Settings": {
"AARTS_ENVIRONMENT": "Staging",
...
}
}
Далее у меня есть три файла json среды. Я просто поместил статический текст для connstring на данный момент для отладки.
appsettings.development.json
{
"ConnectionStrings": {
"AartsConnection" : "DevConn"
}
}
appsettings.staging.json
{
"ConnectionStrings": {
"AartsConnection" : "StagingConn"
}
}
appsettings.production.json
{
"ConnectionStrings": {
"AartsConnection" : "ProdConn"
}
}
Вот наш файл startup.cs.
public Startup(IHostingEnvironment env)
{
var builder = new ConfigurationBuilder()
.SetBasePath(env.ContentRootPath)
.AddJsonFile("appsettings.json")
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true);
builder.AddEnvironmentVariables();
Configuration = builder.Build();
var configEnvironment = Configuration.GetValue<string>("Settings:AARTS_ENVIRONMENT");
env.EnvironmentName = configEnvironment;
_environmentName = env.EnvironmentName;
}
Эта строка:
var configEnvironment = Configuration.GetValue<string>("Settings:AARTS_ENVIRONMENT");
читает нашу среду из нашей настройки AARTS_ENVIRONMENT в нашем главном файле appsettings.json.
И эта строка задает для имени среды значение AARTS_ENVIRONMENT.
env.EnvironmentName = configEnvironment;
С этой настройкой мы можем достичь двух из трех наших целей.
1) Мы можем принимать решения в бритве с помощью помощников тегов среды:
<environment include="Development">
<link href="~/lib/bootstrap/dist/css/bootstrap.css" rel="stylesheet" />
<link href="~/css/site-bundle.css" rel="stylesheet" />
<link href="~/lib/font-awsome/css/font-awesome.css" rel="stylesheet" />
</environment>
<environment exclude="Development">
<link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.min.css"
asp-fallback-href="https://ajax.aspnetcdn.com/ajax/bootstrap/3.3.7/css/bootstrap.min.css"
asp-fallback-test-class="sr-only" asp-fallback-test-property="position" asp-fallback-test-value="absolute" />
<link href="~/css/site-bundle.min.css" rel="stylesheet" />
<link href="~/lib/font-awsome/css/font-awesome.min.css" rel="stylesheet" />
</environment>
Здесь мы можем получить правильные версии CSS-файлов. Полная версия для разработки и свернутые версии для не разработки. Здесь принимаются правильные решения, отражающие значение, которое мы указали в настройках приложения AARTS_ENVIRONMENT.
2) Мы можем принимать решения на основе среды из кода C #.
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
//app.UseExceptionHandler("/Error");
app.UseStatusCodePages();
//app.UseBrowserLink();
}
else
{
//app.UseExceptionHandler("/Home/Error");
app.UseExceptionHandler("/Error");
}
Это отражает нашу собственную переменную среды и принимает правильный путь принятия решения.
Однако наша последняя цель не работает.
3) Загрузите и используйте правильный файл appsettings.environment.json на основе нашего пользовательского параметра AARTS_ENVIRONMENT.
Если я поставлю точку останова при запуске, мы увидим загруженные файлы json.
Я устанавливаю переменную среды в качестве примера:
Теперь я получаю правильную среду, так как у меня установлен Staging для AARTS_ENVIRONMENT в appsettings.json.
Но когда я смотрю на свой ConnString, он извлекает из неправильного файла appsettings.environment.json. Это тянет из dev, а не постановка.
Итак, я посмотрел на мой метод StartUp чуть ближе, и он выглядел как ситуация с курицей или яйцом.
Я добавлял файл appsettings. {Env.EnvironmentName} .json в конструктор конфигурации, прежде чем я прочитал среду из нашего пользовательского параметра и установил имя env.environment для IHostingEnvironment.
Но как вам прочитать имя среды до того, как вы построите конфигурацию с помощью компоновщика конфигурации?
Так что я немного переделал стартап:
public Startup(IHostingEnvironment env)
{
var preBuilder = new ConfigurationBuilder()
.SetBasePath(env.ContentRootPath)
.AddJsonFile("appsettings.json");
var preConfiguration = preBuilder.Build();
var configEnvironment = preConfiguration.GetValue<string>("Settings:AARTS_ENVIRONMENT");
// var configEnvironment = Configuration.GetValue<string>("Settings:AARTS_ENVIRONMENT");
env.EnvironmentName = configEnvironment;
var builder = new ConfigurationBuilder()
.SetBasePath(env.ContentRootPath)
.AddEnvironmentVariables()
.AddJsonFile("appsettings.json")
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true);
Configuration = builder.Build();
_environmentName = env.EnvironmentName;
}
Я создал второй сборщик конфигурации под названием prebuilder, чтобы я мог читать переменную AARTS_ENVIRONMENT из appsettings.json
Затем я использую это значение среды для построения основной конфигурации для веб-приложения:
Теперь, если я поставлю точку останова в StartUp, я вижу, что она теперь читает в appsettings.staging.json:
Но когда я захожу на мою страницу http://localhost:49547/debug/connstring, она все равно говорит DevConn.
Вот мой контроллер отладки:
public class DebugController : Controller
{
private IUtilities _utilities;
public DebugController(IUtilities utilities,
IConfiguration configuration)
{
_utilities = utilities;
Configuration = configuration;
}
IConfiguration Configuration { get; }
// Get current environment for debugging purposes.
public IActionResult Environment()
{
ViewBag.CurrentEnv = _utilities.CurrentEnvironment;
return View();
}
public IActionResult HostPath()
{
ViewBag.HostPath = _utilities.HostPath;
return View();
}
public IActionResult ConnString()
{
string connString = Configuration["ConnectionStrings:AartsConnection"];
ViewBag.Connstring = connString;
return View();
}
}
Мои утилиты довольно большие.
Но вот конструктор:
public Utilities(IHostingEnvironment hostingEnvironment,
IAssignmentRepository assignmentRepo,
IUserRepository userRepo, IHttpContextAccessor httpContextAccessor,
IRecommendationRepository recommendationRepo,
IFindingRepository findingRepo,
IAuditRepository auditRepo,
IAcdRepository acdRepo)
{
_hostingEnvironment = hostingEnvironment;
_assignmentRepo = assignmentRepo;
_userRepo = userRepo;
_httpContextAccessor = httpContextAccessor;
_recommendationRepo = recommendationRepo;
_findingRepo = findingRepo;
_auditRepo = auditRepo;
_acdRepo = acdRepo;
}
и вот соответствующие действия и свойства утилиты:
public string CurrentEnvironment => _hostingEnvironment.EnvironmentName;
public string HostPath =>
$"{_httpContextAccessor.HttpContext.Request.Scheme}://{_httpContextAccessor.HttpContext.Request.Host}{_httpContextAccessor.HttpContext.Request.PathBase}";
Есть ли способ заставить его загрузить правильный файл appsettings.environment.json, основываясь на этом? Я чувствую, что я очень близко.