복습:
먼저 ASP.NET Core GitHub 오픈 소스 주소를 첨부하세요
하이퍼링크 로그인이 보입니다.
하이퍼링크 로그인이 보입니다.
Core 3.1 ASP.NET 새 프로젝트를 생성한 후, 프로그램 코드는 다음과 같습니다:
우리는 GitHub 소스 코드와 결합된 진입 코드를 깊이 파고들었습니다.
호스트 코드:하이퍼링크 로그인이 보입니다.
CreateDefaultBuilder 메서드
여기서는 IHostBuilder에서 상속받은 HostBuilder 객체를 인스턴스화하고, :appsettings.json, appsettings 같은 시스템 정의 대리자를 추가합니다. {env. EnvironmentName}.json 구성 파일이며, 결국 IHostBuilder 인터페이스를 반환할 예정입니다.
HostBuilder 코드:하이퍼링크 로그인이 보입니다.
빌드 메서드는 결국 호출될 것입니다.
공개 IHost 빌드()
{ 만약 (_hostBuilt) { 새로운 InvalidOperationException(SR. BuildCalled); } _hostBuilt = 참;
BuildHostConfiguration(); 호스팅 환경 만들기(); CreateHostBuilderContext(); BuildAppConfiguration(); CreateServiceProvider();
return _appServices.GetRequiredService<IHost>();
} BuildHostConfiguration 메서드
개인 아이콘 피규_hostConfiguration; IConfigurationBuilder configBuilder = new ConfigurationBuilder() 대리인에게 전화해서 차례로 구성을 추가하세요
CreateHostingEnvironment 메서드
private HostingEnvironment _hostingEnvironment; _hostingEnvironment = 새로운 호스팅환경()
{ ApplicationName = _hostConfiguration[HostDefaults.ApplicationKey], EnvironmentName = _hostConfiguration[HostDefaults.EnvironmentKey] ?? 환경.프로덕션, ContentRootPath = ResolveContentRootPath(_hostConfiguration[HostDefaults.ContentRootKey], AppContext.BaseDirectory), }; CreateHostBuilderContext 메서드
private HostBuilderContext _hostBuilderContext; _hostBuilderContext = new HostBuilderContext(Properties)
{ HostingEnvironment = _hostingEnvironment, 구성 = _hostConfiguration }; BuildAppConfiguration 메서드
구성 정보를 다시 통합하세요
IConfigurationBuilder configBuilder = new ConfigurationBuilder() . SetBasePath(_hostingEnvironment.ContentRootPath) . AddConfiguration(_hostConfiguration, shouldDisposeConfiguration: true); _appConfiguration = configBuilder.Build(); _hostBuilderContext.Configuration = _appConfiguration; CreateServiceProvider 메서드
var services = new ServiceCollection(); 서비스를 등록하고, delegate를 호출한 뒤 사용자 정의 서비스를 추가하세요.
GenericHostBuilderExtensions 확장 방법
하이퍼링크 로그인이 보입니다.
ConfigureWebHost 확장 방법
GenericWebHostService를 백엔드 서비스로 등록하려면:
건축가. ConfigureServices((맥락, 서비스) => 서비스. AddHostedService<GenericWebHostService>()); 일반 WebHostService 코드:하이퍼링크 로그인이 보입니다.
공개 비동기 작업 시작(CancellationToken cancellationToken) { HostingEventSource.Log.HostStart();
var serverAddressesFeature = <IServerAddressesFeature>Server.Features.Get(); var addresses = serverAddressesFeature?. 주소; 만약 (addresses != null & !addresses. IsReadOnly & 주소. 카운트 == 0) { var urls = Configuration[WebHostDefaults.ServerUrlsKey]; 만약 (!string. IsNullOrEmpty(urls)) { 서버주소기능!. PreferHostingUrls = WebHostUtilities.ParseBool(Configuration, WebHostDefaults.PreferHostingUrlsKey);
foreach(URL의 var 값. 스플릿('; ', StringSplitOptions.RemoveEmptyEntrys)) { 주소들. 더하기(가치); } } }
요청 위임? application = null;
시도해 { var configure = Options.ConfigureApplication;
if (구성 == null) { throw new InvalidOperationException($"No application configured. IWebHostBuilder.UseStartup, IWebHostBuilder.Configure, 또는 {nameof(WebHostDefaults.StartupAssemblyKey)}에서 시작 어셈블리를 지정하여 애플리케이션을 지정해 주세요. 웹 호스트 구성."); }
var builder = ApplicationBuilderFactory.CreateBuilder(Server.Features);
foreach (StartupFilters.Reverse()의 var 필터) { 구성 = 필터. 구성(구성); }
구성(건축가);
요청 파이프라인을 구축하세요 응용 = 건축가. Build(); } catch (예외 예) { Logger.ApplicationError(ex);
만약 (! Options.WebHostOptions.CaptureStartupErrors) { 던지기; }
var showDetailedErrors = HostingEnvironment.IsDevelopment() || Options.WebHostOptions.DetailedErrors;
application = ErrorPageBuilder.BuildErrorPageApplication(HostingEnvironment.ContentRootFileProvider, Logger, showDetailedErrors, ex); }
var httpApplication = new HostingApplication(application, Logger, DiagnosticListener, HttpContextFactory);
wait, Server.StartAsync(httpApplication, cancellationToken);
만약 (addresses != null) { foreach (주소 내 var 주소) { LifetimeLogger.ListeningOnAddress(address); } }
if (Logger.IsEnabled(LogLevel.Debug)) { foreach (var assembly in Options.WebHostOptions.GetFinalHostingStartupAssemblies()) { Logger.StartupAssemblyLoaded(assembly); } }
if (Options.HostingStartupExceptions != null) { foreach (var exception in Options.HostingStartupExceptions.InnerExceptions) { Logger.HostingStartupAssemblyError(exception); } } }
var webhostBuilder = new GenericWebHostBuilder(builder, webHostBuilderOptions); 하이퍼링크 로그인이 보입니다.
WebHostBuilderExtensions 확장 메서드
IWebHostBuilder 호출을 위한 startupType 객체를 제공합니다.
이 IWebHostBuilder 호스트빌더 if(hostBuilder는 ISupportsStartup supportsStartup입니다)
{ return supportsStartup.UseStartup(startupType);
} 하이퍼링크 로그인이 보입니다.
GenericWebHostBuilder 개인 방법 GenericWebHostBuilder
Startup 객체를 동적으로 인스턴스화하기:
인스턴스 ?? = ActivatorUtilities.CreateInstance(new HostServiceProvider(webHostBuilderContext), startupType); 맥락. 속성[_startupKey] = 인스턴스; ConfigureServices 방법을 찾아보세요
var configureServicesBuilder = StartupLoader.FindConfigureServicesDelegate(startupType, context. HostingEnvironment.EnvironmentName); var configureServices = configureServicesBuilder.Build(instance);
internal static ConfigureServicesBuilder FindConfigureServicesDelegate([DynamicallyAccessedMembers(StartupLinkerOptions.Accessibility)] Type startupTypeType, string environmentName) { var servicesMethod = FindMethod(startupType, "Configure{0}Services", environmentName, typeof(IServiceProvider), required: false) ?? FindMethod(startupType, "Configure{0}Services", environmentName, typeof(void), 필수: false); 새 ConfigureServicesBuilder(servicesMethod)를 반환; ConfigureContainer 메서드를 찾아보세요
var configureContainerBuilder = StartupLoader.FindConfigureContainerDelegate(startupType, context. HostingEnvironment.EnvironmentName);
내부 정적 ConfigureContainerBuilder FindConfigureContainerDelegate([DynamicallyAccessedMembers(StartupLinkerOptions.Accessibility)] Type startupTypeType, string environmentName) { var configureMethod = FindMethod(startupType, "Configure{0}Container", environmentName, typeof(void), required: false); return new ConfigureContainerBuilder(configureMethod); } 구성 메서드를 찾아보세요
configureBuilder = StartupLoader.FindConfigureDelegate(startupType, context. HostingEnvironment.EnvironmentName);
내부 정적 ConfigureBuilder FindConfigureDelegate([DynamicallyAccessedMembers(StartupLinkerOptions.Accessibility)] 유형 startupType, string environmentName)
{ var configureMethod = FindMethod(startupType, "Configure{0}", environmentName, typeof(void), required: true)!; 새 ConfigureBuilder(configureMethod)를 반환;
} ConfigureBuilder의 빌드 메서드로 호출된 소스 코드는 다음과 같습니다:
개인 클래스 ConfigureBuilder { public ConfigureBuilder(MethodInfo configure) { MethodInfo = configure; }
public MethodInfo MethodInfo { get; }
public Action<IApplicationBuilder> Build(객체 인스턴스) { return (applicationBuilder) => Invoke(instance, applicationBuilder); }
private void Invoke(object instance, IApplicationBuilder builder) { var serviceProvider = builder. 애플리케이션서비스; var parameterInfos = MethodInfo.GetParameters(); var parameters = new object[parameterInfos.Length]; (var 지수 = 0; index < parameterInfos.Length; index++) { var parameterInfo = parameterInfos[index]; if (parameterInfo.ParameterType == typeof(IApplicationBuilder)) { 매개변수[index] = 빌더; } 그렇지 않으면 { 시도해 { parameters[index] = serviceProvider.GetRequiredService(parameterInfo.ParameterType); } catch (예외 예) { 새로운 InvalidOperationException( Resources.FormatMiddlewareFilter_ServiceResolutionFail( parameterInfo.ParameterType.FullName, parameterInfo.Name, MethodInfo.Name, MethodInfo.DeclaringType.FullName), ex); } } } MethodInfo.Invoke(인스턴스, 매개변수); } } 런 메서드
HostingAbstractionsHostExtensions 확장 메서드 주소:
하이퍼링크 로그인이 보입니다.
결국 전화를 걸었다:
/// <summary> 애플리케이션을 실행하고, 토큰이 트리거되거나 종료가 발생했을 때만 완료되는 작업을 반환합니다. /// </summary> <param name="host">The <see cref="IHost"/> 실행 시 사용됩니다.</param> <param name="token">종료를 트리거하는 토큰.</param> 비<returns>동기 연산을 나타내는 <참조 cref="Task"/>.</returns> 공개 정적 비동기 작업 RunAsync(이 IHost 호스트, CancellationToken 토큰 = 기본값) { 시도해 { 주인을 기다려. StartAsync(token). ConfigureAwait(false);
주인을 기다려. WaitForShutdownAsync(token). ConfigureAwait(false); } 드디어 { 만약 (호스트는 IAsyncDisposable asyncDisposable) { wait, asyncDisposable.DisposeAsync(). ConfigureAwait(false); } 그렇지 않으면 { 호스트. 처분(); }
} } 이전에 서비스를 구축할 때 IHost 서비스에 등록했는데, 코드는 다음과 같습니다:
서비스. AddSingleton<IHost>(_ => { 새 Internal.Host(_appServices, _appServices.GetRequiredService<IHostApplicationLifetime>(), _appServices.GetRequiredService<ILogger<Internal.Host>>(), _appServices.GetRequiredService<IHostLifetime>(), _appServices.GetRequiredService<IOptions<HostOptions>>()); }); StartAsync 방법
주소:하이퍼링크 로그인이 보입니다.
공개 비동기 작업 시작(CancellationToken cancellationToken= default) { _logger. 스타팅();
var combinedCancellationTokenSource = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken, _applicationLifetime.ApplicationStopping); 취소토큰 결합 취소토큰 = combinedcancellationTokenSource.Token;
wait_hostLifetime.WaitForStartAsync(combinedCancellationToken). ConfigureAwait(false);
combinedCancellationToken.ThrowIfCancellationRequested(); _hostedServices = Services.GetService<IEnumerable<IHostedService>>();
foreach (IHostedService 호스팅된 서비스, _hostedServices) { 화재 서비스. 시작 await hostedService.StartAsync(combinedCancellationToken). ConfigureAwait(false);
if (hostedService는 BackgroundService backgroundService입니다) { _ = HandleBackgroundException(backgroundService); } }
해고: IostApplicationLifetime. 시작됨. _applicationLifetime.NotifyStarted();
_logger. 시작(); } (끝)
|