Resensi:
Mulailah dengan melampirkan alamat sumber terbuka GitHub Inti ASP.NET
Login hyperlink terlihat.
Login hyperlink terlihat.
Setelah membuat proyek baru ASP.NET Core 3.1, kode programnya adalah sebagai berikut:
Kami menyelami kode entri yang dikombinasikan dengan kode sumber GitHub.
Kode Host:Login hyperlink terlihat.
Metode CreateDefaultBuilder
Di sini kita membuat instance objek HostBuilder, yang mewarisi dari IHostBuilder, dan menambahkan delegasi yang ditentukan sistem, seperti :appsettings.json, appsettings. {env. EnvironmentName}.json file konfigurasi, yang pada akhirnya akan mengembalikan: antarmuka IHostBuilder.
Kode HostBuilder:Login hyperlink terlihat.
Metode Build pada akhirnya akan dipanggil.
publik IHost Build()
{ jika (_hostBuilt) { melemparkan InvalidOperationException(SR. BuildCalled); } _hostBuilt = benar;
BuildHostConfiguration(); CreateHostingEnvironment(); CreateHostBuilderContext(); BuildAppConfiguration(); CreateServiceProvider();
return _appServices.GetRequiredService<IHost>();
} Metode BuildHostConfiguration
_hostConfiguration IConfigurasi pribadi; IConfigurationBuilder configBuilder = new ConfigurationBuilder() Panggil delegasi untuk menambahkan konfigurasi secara bergantian
Metode CreateHostingEnvironment
Lingkungan Hosting pribadi _hostingEnvironment; _hostingEnvironment = HostingEnvironment() baru
{ ApplicationName = _hostConfiguration[HostDefaults.ApplicationKey], EnvironmentName = _hostConfiguration[HostDefaults.EnvironmentKey] ?? Lingkungan.Produksi, ContentRootPath = ResolveContentRootPath(_hostConfiguration[HostDefaults.ContentRootKey], AppContext.BaseDirectory), }; Metode CreateHostBuilderContext
HostBuilderContext pribadi _hostBuilderContext; _hostBuilderContext = HostBuilderContext(Properti) baru
{ HostingEnvironment = _hostingEnvironment, Konfigurasi = _hostConfiguration }; Metode BuildAppConfiguration
Mengintegrasikan informasi konfigurasi lagi
IConfigurationBuilder configBuilder = new ConfigurationBuilder() . SetBasePath(_hostingEnvironment.ContentRootPath) . AddConfiguration(_hostConfiguration, shouldDisposeConfiguration: true); _appConfiguration = configBuilder.Build(); _hostBuilderContext.Konfigurasi = _appConfiguration; Metode CreateServiceProvider
var services = serviceCollection baru(); Daftarkan layanan, panggil delegasi, dan tambahkan layanan yang ditentukan pengguna.
Metode ekstensi GenericHostBuilderExtensions
Login hyperlink terlihat.
Metode ekstensi ConfigureWebHost
Untuk mendaftarkan GenericWebHostService sebagai layanan backend:
pembangun. ConfigureServices((konteks, layanan) => layanan. AddHostedService<GenericWebHostService>()); Kode GenericWebHostService:Login hyperlink terlihat.
publik asinkron Tugas StartAsync(PembatalanToken pembatalanToken) { HostingEventSource.Log.HostStart();
var serverAddressesFeature = Server.Features.Get<IServerAddressesFeature>(); var addresses = serverAddressesFeature?. Alamat; if (alamat != null && !addresses. IsReadOnly && alamat. Hitungan == 0) { var urls = Konfigurasi[WebHostDefaults.ServerUrlsKey]; if (!string. IsNullOrEmpty(urls)) { serverAddressesFeature!. PreferHostingUrls = WebHostUtilities.ParseBool(Konfigurasi, WebHostDefaults.PreferHostingUrlsKey);
foreach (nilai var dalam url. Split('; ', StringSplitOptions.RemoveEmptyEntries)) { alamat. Tambahkan(nilai); } } }
RequestDelegate? aplikasi = nol;
Coba { var configure = Options.ConfigureApplication;
if (konfigurasi == null) { lempar baru InvalidOperationException($"Tidak ada aplikasi yang dikonfigurasi. Harap tentukan aplikasi melalui IWebHostBuilder.UseStartup, IWebHostBuilder.Configure, atau tentukan rakitan startup melalui {nameof(WebHostDefaults.StartupAssemblyKey)} di konfigurasi host web."); }
var builder = ApplicationBuilderFactory.CreateBuilder(Server.Features);
foreach (filter var di StartupFilters.Reverse()) { konfigurasi = filter. Konfigurasi (konfigurasikan); }
mengkonfigurasi (pembuat);
Membangun alur permintaan aplikasi = pembangun. Bangun(); } tangkap (Pengecualian mis) { Logger.ApplicationError(mis);
jika (! Options.WebHostOptions.CaptureStartupErrors) { melempar; }
var showDetailedErrors = HostingEnvironment.IsDevelopment() || Options.WebHostOptions.DetailedErrors;
application = ErrorPageBuilder.BuildErrorPageApplication(HostingEnvironment.ContentRootFileProvider, Logger, showDetailedErrors, mis); }
var httpApplication = HostingApplication baru (aplikasi, Logger, DiagnosticListener, HttpContextFactory);
await Server.StartAsync(httpApplication, cancellationToken);
if (alamat != null) { foreach (alamat var dalam alamat) { LifetimeLogger.ListeningOnAddress(alamat); } }
if (Logger.IsEnabled(LogLevel.Debug)) { foreach (rakitan var di Options.WebHostOptions.GetFinalHostingStartupAssemblies()) { Logger.StartupAssemblyLoaded(perakitan); } }
if (Options.HostingStartupExceptions != null) { foreach (var exception di Options.HostingStartupExceptions.InnerExceptions) { Logger.HostingStartupAssemblyError(pengecualian); } } }
var webhostBuilder = GenericWebHostBuilder baru (pembuat, webHostBuilderOptions); Login hyperlink terlihat.
Metode ekstensi WebHostBuilderExtensions
Menyediakan objek startupType untuk panggilan IWebHostBuilder.
hostBuilder IWebHostBuilder ini if (hostBuilder adalah ISupportsStartup supportsStartup)
{ return supportsStartup.UseStartup(startupType);
} Login hyperlink terlihat.
GenericWebHostBuilder Metode Pribadi GenericWebHostBuilder
Membuat instance secara dinamis objek Startup kita:
contoh ?? = ActivatorUtilities.CreateInstance(HostServiceProvider baru(webHostBuilderContext), startupType); konteks. Properties[_startupKey] = instans; Cari metode ConfigureServices
var configureServicesBuilder = StartupLoader.FindConfigureServicesDelegate(startupType, context. HostingEnvironment.EnvironmentName); var configureServices = configureServicesBuilder.Build(instance);
statis internal ConfigureServicesBuilder FindConfigureServicesDelegate([DynamicallyAccessedMembers(StartupLinkerOptions.Accessibility)] Ketik startupType, string environmentName) { var servicesMethod = FindMethod(startupType, "Configure{0}Services", environmentName, typeof(IServiceProvider), required: false) ?? FindMethod(startupType, "Configure{0}Services", environmentName, typeof(void), required: false); mengembalikan ConfigureServicesBuilder(servicesMethod) baru; Cari metode ConfigureContainer
var configureContainerBuilder = StartupLoader.FindConfigureContainerDelegate(startupType, context. HostingEnvironment.EnvironmentName);
statis internal ConfigureContainerBuilder FindConfigureContainerDelegate([DynamicallyAccessedMembers(StartupLinkerOptions.Accessibility)] Ketik startupType, string environmentName) { var configureMethod = FindMethod(startupType, "Configure{0}Container", environmentName, typeof(void), required: false); mengembalikan ConfigureContainerBuilder(configureMethod) baru; } Cari metode Konfigurasi
configureBuilder = StartupLoader.FindConfigureDelegate(startupType, context. HostingEnvironment.EnvironmentName);
statis internal ConfigureBuilder FindConfigureDelegate([DynamicallyAccessedMembers(StartupLinkerOptions.Accessibility)] Ketik startupType, string environmentName)
{ var configureMethod = FindMethod(startupType, "Configure{0}", environmentName, typeof(void), required: true)!; mengembalikan ConfigureBuilder baru(configureMethod);
} Dipanggil oleh metode Build ConfigureBuilder, kode sumbernya adalah sebagai berikut:
kelas privat ConfigureBuilder { publik ConfigureBuilder(MethodInfo configure) { MethodInfo = mengonfigurasi; }
publik MethodInfo MethodInfo { get; }
Build Tindakan publik<IApplicationBuilder>(instance objek) { return (applicationBuilder) => Memanggil(instance, applicationBuilder); }
private void Invoke(instance objek, pembuat IApplicationBuilder) { var serviceProvider = pembuat. Layanan Aplikasi; var parameterInfos = MethodInfo.GetParameters(); var parameter = objek baru[parameterInfos.Length]; untuk (indeks var = 0; indeks < parameterInfos.Length; indeks++) { var parameterInfo = parameterInfos[indeks]; if (parameterInfo.ParameterType == typeof(IApplicationBuilder)) { parameter[indeks] = pembangun; } yang lain { Coba { parameters[index] = serviceProvider.GetRequiredService(parameterInfo.ParameterType); } tangkap (Pengecualian mis) { melempar InvalidOperationException( baru Resources.FormatMiddlewareFilter_ServiceResolutionFail( parameterInfo.ParameterType.FullName, parameterInfo.Name, MethodInfo.Name, MethodInfo.DeclaringType.FullName), mis); } } } MethodInfo.Invoke(instance, parameter); } } Metode jalankan
Alamat metode ekstensi HostingAbstractionsHostExtensions:
Login hyperlink terlihat.
Akhirnya memanggil:
/// <summary> Menjalankan aplikasi dan mengembalikan Tugas yang hanya selesai saat token dipicu atau shutdown dipicu. /// </summary> <param name="host"> <see cref="IHost"/> untuk dijalankan.</param> <param name="token">Token untuk memicu shutdown.</param> <returns><lihat cref="Task"/> yang mewakili operasi asinkron.</returns> publik statis asinkron Task RunAsync(host IHost ini, token CancellationToken = default) { Coba { menunggu tuan rumah. MulaiAsync(token). ConfigureAwait(false);
menunggu tuan rumah. WaitForShutdownAsync(token). ConfigureAwait(false); } akhirnya { if (host adalah IAsyncDisposable asyncDisposable) { await asyncDisposable.DisposeAsync(). ConfigureAwait(false); } yang lain { tuan rumah. Buang (); }
} } Sebelumnya, ketika saya membangun layanan, saya akan mendaftar untuk layanan IHost, dan kodenya adalah sebagai berikut:
layanan. AddSingleton<IHost>(_ => { mengembalikan Internal.Host(_appServices baru, _appServices.GetRequiredService<IHostApplicationLifetime>(), _appServices.GetRequiredService<ILogger<Internal.Host>>(), _appServices.GetRequiredService<IHostLifetime>(), _appServices.GetRequiredService<IOptions<HostOptions>>()); }); Metode StartAsync
Alamat:Login hyperlink terlihat.
publik asinkron Tugas StartAsync(CancellationToken cancellationToken = default) { _logger. Mulai();
menggunakan var combinedCancellationTokenSource = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken, _applicationLifetime.ApplicationStopping); CancellationToken combinedCancellationToken = combinedCancellationTokenSource.Token;
await _hostLifetime.WaitForStartAsync(combinedCancellationToken). ConfigureAwait(false);
combinedCancellationToken.ThrowIfCancellationRequested(); _hostedServices = Services.GetService<IEnumerable<IHostedService>>();
foreach (IHostedService hostedService di _hostedServices) { Layanan Kebakaran IHosted.Mulai await hostedService.StartAsync(combinedCancellationToken). ConfigureAwait(false);
if (hostedService adalah BackgroundService backgroundService) { _ = HandleBackgroundException(backgroundService); } }
// Fire IHostApplicationLifetime.Started _applicationLifetime.NotifyStarted();
_logger. Dimulai(); } (Akhir)
|