Minimal API 中是 WebApplication 和 WebApplicationBuilder
主要介绍 WebApplication
和 WebApplicationBuilder
的使用.
这两个用于创建 ASP.NET Core 的主机 (我是这么理解的).
所谓主机, 可以理解为程序运行的载体. 主机维护了:
- 整个程序的声明周期.
- 各个组件模块.
- 各个中间件.
- 依赖注入系统等.
可以简单将其看成一个运行平台, 类比于虚拟机软件中的虚拟机, 嵌入式开发中的操作系统 (例如宙合的 LuatOS, 鸿蒙等).
使用模板生成代码 (.NET8
)
dotnet new web
然后生成:
var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
app.MapGet("/", () => "Hello World!");
app.Run();
其中
WebAPplication.CreateBuilder()
返回的便是WebApplicationBuiler
对象.builder.Build()
返回的是WebApplication
对象.
从使用的角度看:
WebApplicationBuilder
用于配置主机, 例如中间件, 服务等.WebApplication
即为主机, 用于配置运行时使用的管道服务等, 并用于启动服务.
WebApplication
创建方式:
- 利用
WebApplicationBuilder
的Build
方法来获得. - 直接使用
WebApplication.Create()
来创建.
下面列举使用 它 可以用来处理什么.
使用端口
端口配置可以使用:
- 编辑
Properties/launchSettings.json
文件中的配置 - 给
app.Run()
方法传参. 例如app.Run("http://localhost:3000");
- 向
app.Urls
中添加url
. 例如:app.Urls.Add("http://localhost:3000");
. 这样可以配置多端口. - 使用命令行传参. 例如:
dotnet run --urls="https://localhost:7777"
- 使用环境变量
- 推荐使用
ASPNETCORE_URLS
环境变量. 该环境变量也支持多端口. - 也可以直接使用
var port = Environment.GetEnvironmentVariable("PORT") ?? "3000";
这类语法.
- 推荐使用
- 监听所有接口:
http://*:3000
http://+:3000
http://0.0.0.0:3000
- 使用
ASPNETCORE_HTTPS_PORTS
环境变量. 例如:ASPNETCORE_HTTP_PORTS=3000;5005
和ASPNETCORE_HTTPS_PORTS=5000
.
优先级是一个问题
使用指定开发证书的 HTTPS
在 appsettings.json
中配置证书
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*",
"Kestrel": {
"Certificates": {
"Default": {
"Path": "cert.pem",
"KeyPath": "key.pem"
}
}
}
}
通过配置指定证书 (逻辑与 appsettings.json
是一样的).
// Configure the cert and the key
builder.Configuration["Kestrel:Certificates:Default:Path"] = "cert.pem";
builder.Configuration["Kestrel:Certificates:Default:KeyPath"] = "key.pem";
使用证书 API
builder.WebHost.ConfigureKestrel(options =>
{
options.ConfigureHttpsDefaults(httpsOptions =>
{
var certPath = Path.Combine(builder.Environment.ContentRootPath, "cert.pem");
var keyPath = Path.Combine(builder.Environment.ContentRootPath, "key.pem");
httpsOptions.ServerCertificate = X509Certificate2.CreateFromPemFile(certPath,
keyPath);
});
});
读取环境
使用 app.Environment
来引用环境.
细节参考文档环境.
读取配置
使用 app.Configuration
来引用配置文件. 例如:
var message = app.Configuration["HelloKey"] ?? "Config failed!";
它会读取 appsettings.json
中的 "HelloKey"
键.
细节可以参考文档.
调用日志接口
例如: app.Logger.LogInformation("The app started");
细节可以参考文档.
访问依赖注入容器
这个功能比较有用, 在代码中用于直接访问服务.
using (var scope = app.Services.CreateScope()) {
var sampleService = scope.ServiceProvider.GetRequiredService<SampleService>();
sampleService.DoSomething();
}
细节可以参考文档.
添加中间件
// Setup the file server to serve static files.
app.UseFileServer();
细节可以参考文档.
WebApplicationBuilder
可以直接创建 WebApplication
, 但是如果需要细节控制 (配置各种服务等), 就需要先创建 WebAPplicationBuilder
, 利用它来进行配置, 然后在基于配置好的 WebApplictionBuilder
来创建 WebApplication
.
更改内容根, 应用程序名称和环境
直接创建时通过代码修改
var builder = WebApplication.CreateBuilder(new WebApplicationOptions {
Args = args,
ApplicationName = typeof(Program).Assembly.FullName,
ContentRootPath = Directory.GetCurrentDirectory(),
EnvironmentName = Environments.Staging,
WebRootPath = "customwwwroot"
});
Console.WriteLine($"Application Name: {builder.Environment.ApplicationName}");
Console.WriteLine($"Environment Name: {builder.Environment.EnvironmentName}");
Console.WriteLine($"ContentRoot Path: {builder.Environment.ContentRootPath}");
Console.WriteLine($"WebRootPath: {builder.Environment.WebRootPath}");
var app = builder.Build();
使用环境变量或命令行修改
修改目标 | 使用的环境变量 | 对应的命令行参数 |
---|---|---|
应用程序名称 | ASPNETCORE_APPLICATIONNAME | --applicationName |
环境名称 | ASPNETCORE_ENVIRONMENT | --environment |
内容根 | ASPNETCIRE_CONTENTROOT | --contentRoot |
添加配置提供程序
builder.Configuration.AddIniFile("appsettings.ini");
细节可以参考文档: 文件配置提供程序.
读取配置
默认可以从多个位置读取配置:
appSettings.json
,appSettings.{environment}.json
- 环境变量
- 命令行
细节可以参考文档: 默认配置.
var message = builder.Configuration["HelloKey"] ?? "Hello";
添加日志提供程序
// Configure JSON logging to the console.
builder.Logging.AddJsonConsole();
添加服务
// Add the memory cache services.
builder.Services.AddMemoryCache();
// Add a custom scoped service.
builder.Services.AddScoped<ITodoRepository, TodoRepository>();
自定义 IHostBuilder
利用 Host
属性来访问 IHostBuilder
:
// Wait 30 seconds for graceful shutdown.
builder.Host.ConfigureHostOptions(o => o.ShutdownTimeout = TimeSpan.FromSeconds(30));
自定义 WebHostBuilder
利用 WebHost
属性来访问 IWebHostBuilder
:
// Change the HTTP server implemenation to be HTTP.sys based
builder.WebHost.UseHttpSys();
修改 Web 根
默认情况下, Web 根相对于 wwwroot
文件夹路径的. Web 根是静态文件中间件查找静态文件的位置.
可以使用 WebHostOptions
, 命令行, 或 UseWebRoot
方法来修改:
var builder = WebApplication.CreateBuilder(new WebApplicationOptions {
Args = args,
// Look for static files in webroot
WebRootPath = "webroot"
});
自定义依赖注入容器 (DI 容器)
下面示例使用 Autofac
:
var builder = WebApplication.CreateBuilder(args);
builder.Host.UseServiceProviderFactory(new AutofacServiceProviderFactory());
// Register services directly with Autofac here. Don't
// call builder.Populate(), that happens in AutofacServiceProviderFactory.
builder
.Host
.ConfigureContainer<ContainerBuilder>(builder => {
builder.RegisterModule(new MyApplicationModule())
});
var app = builder.Build();
开发人员异常页
开发人员异常页是默认配置的, 如下, 访问 /
可以看到一个友好的异常页面:
var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
app.MapGet("/", () => {
throw new InvalidOperationException("Oops, the '/' route has thrown an exception.");
});
app.Run();