您现在的位置是:网站首页> 编程资料编程资料
.Net 6中WebApplicationBuilder介绍和用法_自学过程_
2023-05-24
288人已围观
简介 .Net 6中WebApplicationBuilder介绍和用法_自学过程_
介绍
.Net 6为我们带来的一种全新的引导程序启动的方式。与之前的拆分成Program.cs和Startup不同,整个引导启动代码都在Program.cs中。
WebApplicationBuilder builder = WebApplication.CreateBuilder(args);在上篇文章中,我简要描述了如何使用 WebApplication和WebApplicationBuilder配置 ASP.NET Core 应用程序。在这篇文章中,我们来深入看下代码.
正文
我们示例程序的第一步是执行WebApplicationBuilder builder = WebApplication.CreateBuilder(args);创建一个WebApplicationBuilder实例。
从命令行中分配Args参数,并将选项对象传递给WebApplicationBuilder构造函数的WebApplicationOptions
////// Initializes a new instance of the /// Command line arguments ///class with preconfigured defaults. /// The public static WebApplicationBuilder CreateBuilder(string[] args) => new(new() { Args = args });.
WebApplicationOptions和WebApplicationBuilder后面在讲
internal WebApplicationBuilder(WebApplicationOptions options, Action? configureDefaults = null) /// /// Options for configuing the behavior for public class WebApplicationOptions { ///. /// /// The command line arguments. /// public string[]? Args { get; init; } ////// The environment name. /// public string? EnvironmentName { get; init; } ////// The application name. /// public string? ApplicationName { get; init; } ////// The content root path. /// public string? ContentRootPath { get; init; } ////// The web root path. /// public string? WebRootPath { get; init; } }
WebApplicationBuilder由一堆只读属性和一个方法组成Build(),该方法创建了一个WebApplication. 我删除了部分讲解用不到的代码。
如果您熟悉 ASP.NET Core,那么其中许多属性都使用以前版本中的常见类型
- IWebHostEnvironment: 用于检索环境
- IServiceCollection: 用于向 DI 容器注册服务。
- ConfigurationManager: 用于添加新配置和检索配置值。我在之前的文章有讲
- ILoggingBuilder: 用于注册额外的日志提供程序
在WebHost和Host性质很有趣,因为它们暴露出新的类型,ConfigureWebHostBuilder和ConfigureHostBuilder。这些类型分别实现IWebHostBuilder和IHostBuilder。
公开IWebHostBuilder和IHostBuilder接口对于允许从.NET 6 之前的应用程序迁移到新的最小托管,我们如何将的lambda风格配置IHostBuilder与命令式风格的WebApplicationBuilder协调起来,这就是ConfigureHostBuilder和ConfigureWebHostBuilder与一些内部沿来IHostBuilder实现。
public sealed class WebApplicationBuilder { private const string EndpointRouteBuilderKey = "__EndpointRouteBuilder"; private readonly HostBuilder _hostBuilder = new(); private readonly BootstrapHostBuilder _bootstrapHostBuilder; private readonly WebApplicationServiceCollection _services = new(); private readonly List> _hostConfigurationValues; private WebApplication? _builtApplication; /// /// Provides information about the web hosting environment an application is running. /// public IWebHostEnvironment Environment { get; } /// /// A collection of services for the application to compose. This is useful for adding user provided or framework provided services. /// public IServiceCollection Services { get; } /// /// A collection of configuration providers for the application to compose. This is useful for adding new configuration sources and providers. /// public ConfigurationManager Configuration { get; } /// /// A collection of logging providers for the application to compose. This is useful for adding new logging providers. /// public ILoggingBuilder Logging { get; } /// /// An for configuring server specific properties, but not building. /// To build after configuration, call . /// public ConfigureWebHostBuilder WebHost { get; } /// /// An for configuring host specific properties, but not building. /// To build after configuration, call . /// public ConfigureHostBuilder Host { get; } /// /// Builds the . /// /// A configured . public WebApplication Build() { // Wire up the host configuration here. We don't try to preserve the configuration // source itself here since we don't support mutating the host values after creating the builder. _hostBuilder.ConfigureHostConfiguration(builder => { builder.AddInMemoryCollection(_hostConfigurationValues); }); var chainedConfigSource = new TrackingChainedConfigurationSource(Configuration); // Wire up the application configuration by copying the already built configuration providers over to final configuration builder. // We wrap the existing provider in a configuration source to avoid re-bulding the already added configuration sources. _hostBuilder.ConfigureAppConfiguration(builder => { builder.Add(chainedConfigSource); foreach (var (key, value) in ((IConfigurationBuilder)Configuration).Properties) { builder.Properties[key] = value; } }); // This needs to go here to avoid adding the IHostedService that boots the server twice (the GenericWebHostService). // Copy the services that were added via WebApplicationBuilder.Services into the final IServiceCollection _hostBuilder.ConfigureServices((context, services) => { // We've only added services configured by the GenericWebHostBuilder and WebHost.ConfigureWebDefaults // at this point. HostBuilder news up a new ServiceCollection in HostBuilder.Build() we haven't seen // until now, so we cannot clear these services even though some are redundant because // we called ConfigureWebHostDefaults on both the _deferredHostBuilder and _hostBuilder. foreach (var s in _services) { services.Add(s); } // Add the hosted services that were initially added last // this makes sure any hosted services that are added run after the initial set // of hosted services. This means hosted services run before the web host starts. foreach (var s in _services.HostedServices) { services.Add(s); } // Clear the hosted services list out _services.HostedServices.Clear(); // Add any services to the user visible service collection so that they are observable // just in case users capture the Services property. Orchard does this to get a "blueprint" // of the service collection // Drop the reference to the existing collection and set the inner collection // to the new one. This allows code that has references to the service collection to still function. _services.InnerCollection = services; var hostBuilderProviders = ((IConfigurationRoot)context.Configuration).Providers; if (!hostBuilderProviders.Contains(chainedConfigSource.BuiltProvider)) { // Something removed the _hostBuilder's TrackingChainedConfigurationSource pointing back to the ConfigurationManager. // This is likely a test using WebApplicationFactory. Replicate the effect by clearing the ConfingurationManager sources. ((IConfigurationBuilder)Configuration).Sources.Clear(); } // Make builder.Configuration match the final configuration. To do that, we add the additional // providers in the inner _hostBuilders's Configuration to the ConfigurationManager. foreach (var provider in hostBuilderProviders) { if (!ReferenceEquals(provider, chainedConfigSource.BuiltProvider)) { ((IConfigurationBuilder)Configuration).Add(new ConfigurationProviderSource(provider)); } } }); // Run the other callbacks on the final host builder Host.RunDeferredCallbacks(_hostBuilder); _builtApplication = new WebApplication(_hostBuilder.Build()); // Mark the service collection as read-only to prevent future modifications _services.IsReadOnly = true; // Resolve both the _hostBuilder's Configuration and builder.Configuration to mark both as resolved within the // service provider ensuring both will be properly disposed with the provider. _ = _builtApplication.Services.GetService>(); return _builtApplication; } private void ConfigureApplication(WebHostBuilderContext context, IApplicationBuilder app) { Debug.Assert(_builtApplication is not null); // UseRouting called before WebApplication such as in a StartupFilter // lets remove the property and reset it at the end so we don't mess with the routes in the filter if (app.Properties.TryGetValue(EndpointRouteBuilderKey, out var priorRouteBuilder)) { app.Properties.Remove(EndpointRouteBuilderKey); } if (context.HostingEnvironment.IsDevelopment()) { app.UseDeveloperExceptionPage(); } // Wrap the entire destination pipeline in UseRouting() and UseEndpoints(), essentially: // destination.UseRouting() // destination.Run(source) // destination.UseEndpoints() // Set the route builder so that UseRouting will use the WebApplication as the IEndpointRouteBuilder for route matching app.Properties.Add(WebApplication.GlobalEndpointRouteBuilderKey, _builtApplication); // Only call UseRouting() if there are endpoints configured and UseRouting() wasn't called on the global route builder already if (_builtApplication.DataSources.Count > 0) { // If this is set, someone called UseRouting() when a global route builder was already set if (!_builtApplication.Properties.TryGetValue(EndpointRouteBuilderKey, out var localRouteBuilder)) { app.UseRouting(); } else { // UseEndpoints will be looking for the RouteBuilder so make sure it's set app.Properties[EndpointRouteBuilderKey] = localRouteBuilder;
相关内容
- .Net 6简介并和之前版本写法做对比_基础应用_
- ASP.NET Core开发Docker部署_基础应用_
- ASP.NET Core在Linux下为dotnet创建守护进程_基础应用_
- 在Linux+Jexus中发布和部署Asp.Net Core_自学过程_
- 使用.NET 6开发TodoList应用之引入数据存储的思路详解_实用技巧_
- 在MacOS+Linux+Nginx中发布和部署Asp.Net Core_自学过程_
- 使用.NET 6开发TodoList应用之领域实体创建原理和思路_实用技巧_
- .Net Core SDK命令介绍及使用_自学过程_
- Linux下以守护进程方式运行.NET6_实用技巧_
- 将.NET 6项目部署到Linux_基础应用_
点击排行
本栏推荐
