asp.net core 프로필 로드 과정 에 대한 깊이 있 는 이해
설정 파일 에서 프로그램 이 실 행 될 때 없어 서 는 안 되 거나 없어 서 는 안 되 는 역할 을 합 니 다.일반적으로 visual studio 를 사용 하여 프로젝트 를 만 드 는 과정 에서 프로젝트 프로필 은 프로젝트 루트 디 렉 터 리 에 자동 으로 생 성 됩 니 다.예 를 들 어 apptsettings.json 또는 널리 사용 되 는
appsettings.{env.EnvironmentName}.json;
프로필 입 니 다.입구 로 서 코드 를 업데이트 하지 않 는 상황 에서 프로그램 에 관여 하고 조정 할 수 있 습 니 다.그러면 로 딩 과정 에 대한 전면적 인 이해 가 필요 합 니 다.
기본 프로필 을 언제 불 러 왔 습 니까?
Program.cs 파일 에서 다음 코드 를 보십시오.
public class Program
{
public static void Main(string[] args)
{
CreateWebHostBuilder(args).Build().Run();
}
public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>();
}
WebHost.CreateDefaultBuilder
프로그램 집합Microsoft.AspNetCore.dll
에 있 습 니 다.프로그램 이 실 행 될 때WebHost.CreateDefaultBuilder(args)
Create Default Builder 방법 내부 에 기본 설정 파일 을 불 러 왔 습 니 다.코드 는 다음 과 같다.
public static IWebHostBuilder CreateDefaultBuilder(string[] args)
{
var builder = new WebHostBuilder();
if (string.IsNullOrEmpty(builder.GetSetting(WebHostDefaults.ContentRootKey)))
{
builder.UseContentRoot(Directory.GetCurrentDirectory());
}
if (args != null)
{
builder.UseConfiguration(new ConfigurationBuilder().AddCommandLine(args).Build());
}
builder.UseKestrel((builderContext, options) =>
{
options.Configure(builderContext.Configuration.GetSection("Kestrel"));
})
.ConfigureAppConfiguration((hostingContext, config) =>
{
var env = hostingContext.HostingEnvironment;
config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: true);
if (env.IsDevelopment())
{
var appAssembly = Assembly.Load(new AssemblyName(env.ApplicationName));
if (appAssembly != null)
{
config.AddUserSecrets(appAssembly, optional: true);
}
}
config.AddEnvironmentVariables();
if (args != null)
{
config.AddCommandLine(args);
}
})
.ConfigureLogging((hostingContext, logging) =>
{
logging.AddConfiguration(hostingContext.Configuration.GetSection("Logging"));
logging.AddConsole();
logging.AddDebug();
logging.AddEventSourceLogger();
})
.ConfigureServices((hostingContext, services) =>
{
// Fallback
services.PostConfigure<HostFilteringOptions>(options =>
{
if (options.AllowedHosts == null || options.AllowedHosts.Count == 0)
{
// "AllowedHosts": "localhost;127.0.0.1;[::1]"
var hosts = hostingContext.Configuration["AllowedHosts"]?.Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries);
// Fall back to "*" to disable.
options.AllowedHosts = (hosts?.Length > 0 ? hosts : new[] { "*" });
}
});
// Change notification
services.AddSingleton<IOptionsChangeTokenSource<HostFilteringOptions>>(
new ConfigurationChangeTokenSource<HostFilteringOptions>(hostingContext.Configuration));
services.AddTransient<IStartupFilter, HostFilteringStartupFilter>();
})
.UseIIS()
.UseIISIntegration()
.UseDefaultServiceProvider((context, options) =>
{
options.ValidateScopes = context.HostingEnvironment.IsDevelopment();
});
return builder;
}
이 를 통 해 알 수 있 듯 이 Create Default Builder 내부 에 서 는 IConfigurationBuilder 를 사 용 했 고 기본 설정 파일 의 이름 을 적 었 습 니 다.
public static IWebHostBuilder CreateDefaultBuilder(string[] args)
{
var builder = new WebHostBuilder();
if (string.IsNullOrEmpty(builder.GetSetting(WebHostDefaults.ContentRootKey)))
{
builder.UseContentRoot(Directory.GetCurrentDirectory());
}
if (args != null)
{
builder.UseConfiguration(new ConfigurationBuilder().AddCommandLine(args).Build());
}
builder.UseKestrel((builderContext, options) =>
{
options.Configure(builderContext.Configuration.GetSection("Kestrel"));
})
.ConfigureAppConfiguration((hostingContext, config) =>
{
var env = hostingContext.HostingEnvironment;
config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: true);
if (env.IsDevelopment())
{
var appAssembly = Assembly.Load(new AssemblyName(env.ApplicationName));
if (appAssembly != null)
{
config.AddUserSecrets(appAssembly, optional: true);
}
}
config.AddEnvironmentVariables();
if (args != null)
{
config.AddCommandLine(args);
}
})
.ConfigureLogging((hostingContext, logging) =>
{
logging.AddConfiguration(hostingContext.Configuration.GetSection("Logging"));
logging.AddConsole();
logging.AddDebug();
logging.AddEventSourceLogger();
})
.ConfigureServices((hostingContext, services) =>
{
// Fallback
services.PostConfigure<HostFilteringOptions>(options =>
{
if (options.AllowedHosts == null || options.AllowedHosts.Count == 0)
{
// "AllowedHosts": "localhost;127.0.0.1;[::1]"
var hosts = hostingContext.Configuration["AllowedHosts"]?.Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries);
// Fall back to "*" to disable.
options.AllowedHosts = (hosts?.Length > 0 ? hosts : new[] { "*" });
}
});
// Change notification
services.AddSingleton<IOptionsChangeTokenSource<HostFilteringOptions>>(
new ConfigurationChangeTokenSource<HostFilteringOptions>(hostingContext.Configuration));
services.AddTransient<IStartupFilter, HostFilteringStartupFilter>();
})
.UseIIS()
.UseIISIntegration()
.UseDefaultServiceProvider((context, options) =>
{
options.ValidateScopes = context.HostingEnvironment.IsDevelopment();
});
return builder;
}
상기 코드 때문에,우 리 는 응용 프로그램 루트 디 렉 터 리 에서appsettings.json
와appsettings.{env.EnvironmentName}.json
이런 형식의 기본 프로필 이름 을 사용 할 수 있 습 니 다또한,Main 방법 으로 기본 설정 파일 을 Build 방법 으로 호출 하 였 습 니 다.
public static void Main(string[] args)
{
CreateWebHostBuilder(args).Build().Run();
}
Startup.cs 에서 주 입 된 방식 으로 기본 설정 파일 대상 IConfigurationRoot/IConfiguration,코드 세 션 을 얻 을 수 있 습 니 다.
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
빌 드 방법 을 실행 할 때 방법 내부 에 기본 설정 파일 대상 을 ServiceCollection,코드 세 션 에 추가 하 였 기 때 문 입 니 다.
var services = new ServiceCollection();
services.AddSingleton(_options);
services.AddSingleton<IHostingEnvironment>(_hostingEnvironment);
services.AddSingleton<Extensions.Hosting.IHostingEnvironment>(_hostingEnvironment);
services.AddSingleton(_context);
var builder = new ConfigurationBuilder()
.SetBasePath(_hostingEnvironment.ContentRootPath)
.AddConfiguration(_config);
_configureAppConfigurationBuilder?.Invoke(_context, builder);
var configuration = builder.Build();
services.AddSingleton<IConfiguration>(configuration);
_context.Configuration = configuration;
이 코드 는 Startup.cs 파일 에서 ServiceCollection 대상 을 사용 하여 업무 시스템 의 사용자 정의 대상 을 서비스 컨 텍스트 에 추가 하여 후속 인터페이스 주입 에 편리 하 게 사용 할 수 있 기 때문에 매우 익숙 합 니 다.AddJSonFile 방법의 사용
일반적으로 저 희 는 기본 프로필 을 사용 하여 개발 하거나 apptsettings.{env.Environment Name}.json 의 파일 이름 방식 으로 개발/테스트/제품 환경 을 구분 하고 환경 변수 에 따라 서로 다른 프로필 을 불 러 옵 니 다.그러나 이렇게 되면 또 다른 관리 상의 문제,제품 환경의 배치 파라미터 와 개발 환경 을 가 져 왔 다.
환경 변 수 를 사용 하여 설정 파일 의 로드 를 제어 하면 암호 유출 등 위험 을 초래 할 수 있 습 니 다.물론 제품 환경 에서 수 동 으로 이 파일 을 만 들 수 있 지만,이렇게 되면 발표 절차 가 매우 번 거 로 워 지고,조금 이라도 누락 된 파일 은 덮어 쓸 수 있다.
AddJSonFile 로 제품 환경 설정 을 불 러 오 는 것 을 추천 합 니 다.코드 는 다음 과 같 습 니 다.
public Startup(IConfiguration configuration, IHostingEnvironment env)
{
Configuration = AddCustomizedJsonFile(env).Build();
}
public ConfigurationBuilder AddCustomizedJsonFile(IHostingEnvironment env)
{
var build = new ConfigurationBuilder();
build.SetBasePath(env.ContentRootPath).AddJsonFile("appsettings.json", true, true);
if (env.IsProduction())
{
build.AddJsonFile(Path.Combine("/data/sites/config", "appsettings.json"), true, true);
}
return build;
}
AddCustomizedJSonFile 방법 을 통 해 ConfigurationBuilder 대상 을 만 들 고 시스템 의 기본 ConfigurationBuilder 대상 을 덮어 씁 니 다.방법 내부 에서 개발 환경의 프로필 을 기본적으로 불 러 옵 니 다.제품 모드 에서 디 렉 터 리/data/sites/config/appstettings.json 파일 을 추가 로 불 러 옵 니 다.프로필 충돌 문 제 를 걱정 하지 않 습 니 다.같은 키 의 내용 은 나중에 추 가 된 프로필 로 덮어 씁 니 다.
프로필 변경
AddJSonFile 을 호출 할 때,우 리 는 이 방법 이 모두 5 개의 과부하 방법 이 있 는 것 을 보 았 다.
그 중 하 나 는 4 개의 인 자 를 포함 하고 코드 는 다음 과 같다.
public static IConfigurationBuilder AddJsonFile(this IConfigurationBuilder builder, IFileProvider provider, string path, bool optional, bool reloadOnChange)
{
if (builder == null)
{
throw new ArgumentNullException(nameof(builder));
}
if (string.IsNullOrEmpty(path))
{
throw new ArgumentException(Resources.Error_InvalidFilePath, nameof(path));
}
return builder.AddJsonFile(s =>
{
s.FileProvider = provider;
s.Path = path;
s.Optional = optional;
s.ReloadOnChange = reloadOnChange;
s.ResolveFileProvider();
});
}
이 방법 에서 하나의 매개 변수 bool reloadOnChange 가 있 습 니 다.매개 변수 설명 을 통 해 알 수 있 듯 이 이 값 은 파일 이 변동 할 때 다시 불 러 올 지 여 부 를 표시 합 니 다.기본 값 은 false 입 니 다.일반적으로 설정 파일 을 수 동 으로 불 러 옵 니 다.즉,AddJSonFile 방법 을 호출 할 때 이 매개 변 수 를 true 로 설정 하 는 것 을 권장 합 니 다.그러면.net core 는 이 매개 변수 reloadOnChange 를 통 해 파일 의 변동 을 감시 하고 언제 다시 불 러 오 는 지 확인 할 수 있 습 니 다.아래 코드 를 보 세 요.
public IConfigurationRoot Build()
{
var providers = new List<IConfigurationProvider>();
foreach (var source in Sources)
{
var provider = source.Build(this);
providers.Add(provider);
}
return new ConfigurationRoot(providers);
}
우리 가.build 방법 을 실행 할 때 방법 내부 의 마지막 줄 코드 는 AddJSonFile 방법의 매개 변 수 를 이용 하여 ConfigurationRoot 대상 을 만 들 고 되 돌려 주 었 습 니 다.ConfigurationRoot 의 구조 방법 에서
public ConfigurationRoot(IList<IConfigurationProvider> providers)
{
if (providers == null)
{
throw new ArgumentNullException(nameof(providers));
}
_providers = providers;
foreach (var p in providers)
{
p.Load();
ChangeToken.OnChange(() => p.GetReloadToken(), () => RaiseChanged());
}
}
방법 내부 에서 AddJSonFile 방법 으로 추 가 된 프로필 을 한 번 에 읽 고 각 프로필 에 감청 기 ChangeToken 을 따로 할당 하 며 현재 파일 읽 기 대상 IConfigurationProvider.GetReloadToken
방법 을 감청 기 에 연결 하 는 것 을 보 았 습 니 다.파일 이 변동 이 생 겼 을 때 모니터 는 통 지 를 받 고 이 파일 에 대해 원자 작업 을 수행 합 니 다.
private void RaiseChanged()
{
var previousToken = Interlocked.Exchange(ref _changeToken, new ConfigurationReloadToken());
previousToken.OnReload();
}
AddJSonFile 방법 내부 에 JSonConfigurationSource 를 사 용 했 기 때문에 Build 의 재 부팅 방법 은 JSonConfigurationProvider 읽 기 대상 을 구성 하여 코드 를 봅 니 다.
public override IConfigurationProvider Build(IConfigurationBuilder builder)
{
EnsureDefaults(builder);
return new JsonConfigurationProvider(this);
}
JSonConfigurationProvider 에서 FileConfigurationProvider 클래스 를 계승 합 니 다.이 클래스 는 프로그램 집합Microsoft.Extensions.Configuration.Json.dll
에 있 습 니 다.FileConfigurationProvider 의 구조 방법 에서 모니터 가 프로필 을 다시 불 러 오 는 과정 을 실현 하 였 습 니 다.
public FileConfigurationProvider(FileConfigurationSource source)
{
if (source == null)
{
throw new ArgumentNullException(nameof(source));
}
Source = source;
if (Source.ReloadOnChange && Source.FileProvider != null)
{
ChangeToken.OnChange(
() => Source.FileProvider.Watch(Source.Path),
() => {
Thread.Sleep(Source.ReloadDelay);
Load(reload: true);
});
}
}
주의해 야 할 것 은 이 감청 기 는 파일 변동 통 지 를 받 은 후 가장 먼저 설정 파일 을 다시 불 러 오 는 것 이 아니 라 방법 내부 에서 볼 수 있 습 니 다.여기Thread.Sleep(Source.ReloadDelay)
가 있 습 니 다.ReloadDelay 의 기본 값 은 250 ms 입 니 다.이 속성 은 다음 과 같 습 니 다.이상 은 asp.netcore 에서 파일 을 불 러 오 는 내부 실행 과정 입 니 다.기본 프로필 을 어떻게 불 러 오 는 지,기본 프로필 을 시스템 에 어떻게 주입 하 는 지,서로 다른 환경 에서 사용자 정의 프로필 을 불 러 오 는 과정 도 배 웠 습 니 다.그러나 프로필 이 바 뀌 었 을 때 시스템 내 부 는 어떻게 프로필 을 메모리 에 다시 불 러 옵 니까?
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Tailwind를 ASP.NET Core 프로젝트에 통합우리는 을 사용합니다. 에서 코드를 찾을 수 있습니다. 면도기 페이지 구조를 추가합니다. "node_modules"가 설치되었습니다. "tailwind.config.js"파일이 생성되었습니다. 모든 .razor 및 ...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.