Artikel ini adalah artikel cermin dari terjemahan mesin, silakan klik di sini untuk melompat ke artikel aslinya.

Melihat: 59583|Jawab: 1

[Sumber] ASP.NET Inti (7) Analisis mendalam dari kode sumber kerangka kerja

[Salin tautan]
Dipaparkan pada 2021-3-24 13:43:28 | | |
Resensi:

ASP.NET Core (VI) DI secara manual memperoleh metode penyuntikan objek
https://www.itsvse.com/thread-9595-1-1.html

ASP.NET Core (lima) didasarkan pada transaksi distribusi CAP
https://www.itsvse.com/thread-9593-1-1.html

ASP.NET Core(4) memfilter validasi model ModelState terpadu
https://www.itsvse.com/thread-9589-1-1.html

ASP.NET Inti (iii) Membuat instans secara dinamis menggunakan ActivatorUtilities
https://www.itsvse.com/thread-9488-1-1.html

ASP.NET Inti (2) Mulai ulang aplikasi dengan kode
https://www.itsvse.com/thread-9480-1-1.html

ASP.NET Core (1) menggunakan caching Redis
https://www.itsvse.com/thread-9393-1-1.html
Mulailah dengan melampirkan alamat sumber terbuka GitHub Inti ASP.NET

Login hyperlink terlihat.
Login hyperlink terlihat.


asp.net Alamat kode sumber inti
https://www.itsvse.com/thread-9394-1-1.html


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)




Mantan:Laporan pendatang baru yang terlambat
Depan:Kesalahan .NET Core dalam bundel aplikasi pemrosesan Kegagalan Linux
Dipaparkan pada 2021-9-22 20:45:12 |
Belajar untuk belajar...
Sanggahan:
Semua perangkat lunak, materi pemrograman, atau artikel yang diterbitkan oleh Code Farmer Network hanya untuk tujuan pembelajaran dan penelitian; Konten di atas tidak boleh digunakan untuk tujuan komersial atau ilegal, jika tidak, pengguna akan menanggung semua konsekuensi. Informasi di situs ini berasal dari Internet, dan sengketa hak cipta tidak ada hubungannya dengan situs ini. Anda harus sepenuhnya menghapus konten di atas dari komputer Anda dalam waktu 24 jam setelah pengunduhan. Jika Anda menyukai program ini, harap dukung perangkat lunak asli, pembelian pendaftaran, dan dapatkan layanan asli yang lebih baik. Jika ada pelanggaran, silakan hubungi kami melalui email.

Mail To:help@itsvse.com