Tento článek je zrcadlovým článkem o strojovém překladu, klikněte zde pro přechod na původní článek.

Pohled: 59583|Odpověď: 1

[Zdroj] ASP.NET Jádro (7) Hloubková analýza zdrojového kódu frameworku

[Kopírovat odkaz]
Zveřejněno 24. 3. 2021 13:43:28 | | |
Přezkoumání:

ASP.NET Core (VI) DI ručně získává metodu vstřikování objektů
https://www.itsvse.com/thread-9595-1-1.html

ASP.NET Core (pět) je založen na distribuovaných transakcích podle CAP
https://www.itsvse.com/thread-9593-1-1.html

ASP.NET Filtr Core(4) sjednocený validace modelů ModelState
https://www.itsvse.com/thread-9589-1-1.html

ASP.NET Jádro (iii) Dynamicky vytvářet instance pomocí ActivatorUtilities
https://www.itsvse.com/thread-9488-1-1.html

ASP.NET Jádro (2) Restartovat aplikaci pomocí kódu
https://www.itsvse.com/thread-9480-1-1.html

ASP.NET Core (1) používá Redis caching
https://www.itsvse.com/thread-9393-1-1.html
Začněte připojením open source adresy ASP.NET Core GitHub

Přihlášení k hypertextovému odkazu je viditelné.
Přihlášení k hypertextovému odkazu je viditelné.


asp.net Adresa zdrojového kódu jádra
https://www.itsvse.com/thread-9394-1-1.html


Po vytvoření nového projektu ASP.NET Core 3.1 je kód programu následující:

Důkladně jsme se ponořili do vstupního kódu v kombinaci se zdrojovým kódem GitHubu.

Kód hostitele:Přihlášení k hypertextovému odkazu je viditelné.

Metoda CreateDefaultBuilder

Zde instancujeme objekt HostBuilder, který dědí z IHostBuilderu, a přidáváme systémově definované delegáty, jako jsou :appsettings.json, appsettings. {env. EnvironmentName}.json konfigurační soubor, který nakonec vrátí: rozhraní IHostBuilder.

Kód HostBuilderu:Přihlášení k hypertextovému odkazu je viditelné.

Metoda Build bude nakonec vyvolána.


public IHost Build()
{
    pokud (_hostBuilt)
    {
        vyhodit nový InvalidOperationException(SR. BuildCalled);
    }
    _hostBuilt = pravda;

    BuildHostConfiguration();
    CreateHostingEnvironment();
    CreateHostBuilderContext();
    BuildAppConfiguration();
    CreateServiceProvider();

    return _appServices.GetRequiredService<IHost>();
}
Metoda BuildHostConfiguration

soukromý _hostConfiguration IConfigurace;
IConfigurationBuilder configBuilder = nový ConfigurationBuilder()
Zavolejte delegáta, aby následně přidal konfiguraci

Metoda CreateHostingEnvironment

soukromé HostingEnvironment _hostingEnvironment;
_hostingEnvironment = nový HostingEnvironment()
{
    ApplicationName = _hostConfiguration[HostDefaults.ApplicationKey],
    EnvironmentName = _hostConfiguration[HostDefaults.EnvironmentKey] ?? Prostředí. Produkce,
    ContentRootPath = ResolveContentRootPath(_hostConfiguration[HostDefaults.ContentRootKey], AppContext.BaseDirectory),
};
Metoda CreateHostBuilderContext

soukromý HostBuilderContext _hostBuilderContext;
_hostBuilderContext = nový HostBuilderContext(Properties)
{
    HostingEnvironment = _hostingEnvironment,
    Konfigurace = _hostConfiguration
};
Metoda BuildAppConfiguration

Znovu integrujte konfigurační informace

IConfigurationBuilder configBuilder = nový ConfigurationBuilder()
                . SetBasePath(_hostingEnvironment.ContentRootPath)
                . AddConfiguration(_hostConfiguration, shouldDisposeConfiguration: true);
_appConfiguration = configBuilder.Build();
            _hostBuilderContext.Konfigurace = _appConfiguration;
Metoda CreateServiceProvider

var services = nová ServiceCollection();
Zaregistrujte službu, zavolejte delegáta a přidejte uživatelem definovanou službu.

Metoda rozšíření GenericHostBuilderExtensions

Přihlášení k hypertextovému odkazu je viditelné.

Metoda rozšíření ConfigureWebHost

Pro registraci GenericWebHostService jako backendové služby:


stavitel. ConfigureServices((context, services) => services. AddHostedService<GenericWebHostService>());
GenericWebHostService kód:Přihlášení k hypertextovému odkazu je viditelné.


public async Task StartAsync(CancellationToken cancellationToken)
        {
            HostingEventSource.Log.HostStart();

            var serverAddressesFeature = Server.Features.Get<IServerAddressesFeature>();
            var addresses = serverAddressesFeature?. Adresy;
            if (adresy != null & !adresy. IsReadOnly & addresses. Počet == 0)
            {
                var urls = Configuration[WebHostDefaults.ServerUrlsKey];
                if (!string. IsNullOrEmpty(urls))
                {
                    serverAddressesFeature!. PreferHostingUrls = WebHostUtilities.ParseBool(Configuration, WebHostDefaults.PreferHostingUrlsKey);

                    Foreach (hodnota VAR v URL. Split('; ', StringSplitOptions.RemoveEmptyEntries))
                    {
                        adresy. Add(value);
                    }
                }
            }

            RequestDelege? aplikace = null;

            zkus
            {
                var configure = Options.ConfigureApplication;

                if (configure == null)
                {
                    throw new InvalidOperationException($"Žádná aplikace není nakonfigurována. Zadejte prosím aplikaci pomocí IWebHostBuilder.UseStartup, IWebHostBuilder.Configure, nebo zadejte startovací assembler pomocí {nameof(WebHostDefaults.StartupAssemblyKey)} v konfigurace webového hostitele.");
                }

                var builder = ApplicationBuilderFactory.CreateBuilder(Server.Features);

                foreach (var filter in StartupFilters.Reverse())
                {
                    configure = filtr. konfigurovat (konfigurovat);
                }

                configure(builder);

                Vytvořte pipeline požadavků
                aplikace = stavitel. build();
            }
            chytit (Výjimka ex)
            {
                Logger.ApplicationError(ex);

                pokud (! Options.WebHostOptions.CaptureStartupErrors)
                {
                    hod;
                }

                var showDetailedErrors = HostingEnvironment.IsDevelopment() || Options.WebHostOptions.DetailedErrors;

                application = ErrorPageBuilder.BuildErrorPageApplication(HostingEnvironment.ContentRootFileProvider, Logger, showDetailedErrors, ex);
            }

            var httpApplication = nový HostingApplication(application, Logger, DiagnosticListener, HttpContextFactory);

            await Server.StartAsync(httpApplication, cancellationToken);

            if (adresuje != null)
            {
                foreach (VAR adresa v adresách)
                {
                    LifetimeLogger.ListeningOnAddress(adresa);
                }
            }

            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 = nový GenericWebHostBuilder(builder, webHostBuilderOptions);
Přihlášení k hypertextovému odkazu je viditelné.

Metoda rozšíření WebHostBuilderExtensions

Poskytuje objekt startupType pro volání IWebHostBuilder.

tento IWebHostBuilder hostBuilder
pokud (hostBuilder is ISupportsStartup supportsStartup)
{
    return supportsStartup.UseStartup(startupType);
}
Přihlášení k hypertextovému odkazu je viditelné.

GenericWebHostBuilder Private Method GenericWebHostBuilder

Dynamicky instancujte náš Startup objekt:

instance ?? = ActivatorUtilities.CreateInstance (nový HostServiceProvider(webHostBuilderContext), startType);
Kontext. Vlastnosti[_startupKey] = instance;
Hledejte metodu ConfigureServices

var configureServicesBuilder = StartupLoader.FindConfigureServicesDelegate(startupType, context. HostingEnvironment.EnvironmentName);
                var configureServices = configureServicesBuilder.Build(instance);

internal static ConfigureServicesBuilder FindConfigureServicesDelegate([DynamicallyAccessedMembers(StartupLinkerOptions.Accessibility)] Zadejte 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);
            return new ConfigureServicesBuilder(servicesMethod);
Hledejte metodu ConfigureContainer

var configureContainerBuilder = StartupLoader.FindConfigureContainerDelegate(startupType, context. HostingEnvironment.EnvironmentName);

internal static ConfigureContainerBuilder FindConfigureContainerDelegate([DynamicallyAccessedMembers(StartupLinkerOptions.Accessibility)] Zadejte startupType, string environmentName)
        {
            var configureMethod = FindMethod(startupType, "Configure{0}Container", environmentName, typeof(void), required: false);
            return new ConfigureContainerBuilder(configureMethod);
        }
Hledejte metodu Configure

configureBuilder = StartupLoader.FindConfigureDelegate(startupType, context. HostingEnvironment.EnvironmentName);

internal static ConfigureBuilder FindConfigureDelegate([DynamicallyAccessedMembers(StartupLinkerOptions.Accessibility)] Zadejte startupType, string environmentName)
{
    var configureMethod = FindMethod(startupType, "Configure{0}", environmentName, typeof(void), required: true)!;
    return new ConfigureBuilder(configureMethod);
}
Zdrojový kód je volán metodou Build v ConfigureBuilder a je následující:

soukromá třída ConfigureBuilder
        {
            public ConfigureBuilder(MethodInfo configure)
            {
                MethodInfo = konfigurovat;
            }

            public MethodInfo MethodInfo { get; }

            public<IApplicationBuilder> Action Build (instance objektu)
            {
                return (applicationBuilder) => Invoke(instance, applicationBuilder);
            }

            private void Invoke(instance objektu, IApplicationBuilder builder)
            {
                var serviceProvider = builder. ApplicationServices;
                var parameterInfos = MethodInfo.GetParameters();
                parametr var = nový objekt[parameterInfos.Length];
                pro (var index = 0; index < parametrInfos.Length; index++)
                {
                    var parameterInfo = parameterInfos[index];
                    if (parameterInfo.ParameterType == typeof(IApplicationBuilder))
                    {
                        parametry[index] = stavitel;
                    }
                    jinak
                    {
                        zkus
                        {
                            parameters[index] = serviceProvider.GetRequiredService(parameterInfo.ParameterType);
                        }
                        chytit (Výjimka ex)
                        {
                            vyhodit novou InvalidOperationException(
                                Resources.FormatMiddlewareFilter_ServiceResolutionFail(
                                    parameterInfo.ParameterType.FullName,
                                    parameterInfo.Name,
                                    MethodInfo.Name,
                                    MethodInfo.DeclaringType.FullName),
                                ex);
                        }
                    }
                }
                MethodInfo.Invoke(instance, parametry);
            }
        }
Metoda běhu

Adresa metody rozšíření HostingAbstractionsHostExtensions:

Přihlášení k hypertextovému odkazu je viditelné.


Nakonec zavolá:

/// <summary>
        Spustí aplikaci a vrátí úkol, který se dokončí pouze tehdy, když je token spuštěn nebo vypnutí.
        /// </summary>
        <název parametru="host"><Viz cref="IHost"/> běžet.</param>
        <název parametru="token">Token pro spuštění vypnutí.</param>
        <returns><viz cref="Task"/> představuje asynchronní operaci.</returns>
        public static async Task RunAsync (tento IHost host, CancellationToken token = výchozí)
        {
            zkus
            {
                Čekejte na hostitele. StartAsync(token). ConfigureAwait(false);

                Čekejte na hostitele. WaitForShutdownAsync(token). ConfigureAwait(false);
            }
            Konečně
            {
                if (host is IAsyncDisposable asyncDisposable)
                {
                    await asyncDisposable.DisposeAsync(). ConfigureAwait(false);
                }
                jinak
                {
                    hostitel. Dispose();
                }

            }
        }
Dříve, když jsem budoval službu, registroval jsem se do služby IHost a kód byl následující:

Služby. AddSingleton<IHost>(_ =>
            {
                return new Internal.Host(_appServices,
                    _appServices.GetRequiredService<IHostApplicationLifetime>(),
                    _appServices.GetRequiredService<ILogger<Internal.Host>>(),
                    _appServices.GetRequiredService<IHostLifetime>(),
                    _appServices.GetRequiredService<IOptions<HostOptions>>());
            });
Metoda StartAsync

Adresa:Přihlášení k hypertextovému odkazu je viditelné.

public async Task StartAsync(CancellationToken cancellationToken = výchozí)
        {
            _logger. Starting();

            použitím 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 v _hostedServices)
            {
                // Fire IHostedService.Start
                await hostedService.StartAsync (combinedCancellationToken). ConfigureAwait(false);

                if (hostedService is BackgroundService backgroundServiceServices)
                {
                    _ = HandleBackgroundException(backgroundService);
                }
            }

            // Fire IHostApplicationLifetime.Started
            _applicationLifetime.NotifyStarted();

            _logger. Started();
        }
(Konec)




Předchozí:Pozdní zprávy nováčků
Další:.NET Core chyba v balíčku aplikací Linux Failure Processing
Zveřejněno 22. 9. 2021 20:45:12 |
Uč se učit...
Zřeknutí se:
Veškerý software, programovací materiály nebo články publikované organizací Code Farmer Network slouží pouze k učení a výzkumu; Výše uvedený obsah nesmí být používán pro komerční ani nelegální účely, jinak nesou všechny důsledky uživatelé. Informace na tomto webu pocházejí z internetu a spory o autorská práva s tímto webem nesouvisí. Musíte výše uvedený obsah ze svého počítače zcela smazat do 24 hodin od stažení. Pokud se vám program líbí, podporujte prosím originální software, kupte si registraci a získejte lepší skutečné služby. Pokud dojde k jakémukoli porušení, kontaktujte nás prosím e-mailem.

Mail To:help@itsvse.com