尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

Clean Architecture 解决方案中的 Aspire Host:用 .NET Aspire 一键编排 SQL Server、SMTP 与 Web 应用的完整指南

Clean Architecture 解决方案中的 Aspire Host:用 .NET Aspire 一键编排 SQL Server、SMTP 与 Web 应用的完整指南 Clean Architecture 解决方案中的 Aspire Host用 .NET Aspire 一键编排 SQL Server、SMTP 与 Web 应用的完整指南【免费下载链接】CleanArchitectureClean Architecture Solution Template: A proven Clean Architecture Template for ASP.NET Core 10项目地址: https://gitcode.com/GitHub_Trending/cl/CleanArchitecture本文基于 Clean.Architecture.AspireHost 的 README 展开讲解如何用 .NET Aspire 作为启动项目一条命令拉起 SQL Server 容器、Papercut SMTP 邮件测试容器和 Web 应用并自动完成连接字符串注入、数据库等待与迁移读完后可掌握 Aspire 资源图Resource Graph的编写方式、ContainerLifetime.Persistent持久化配置以及绕过 Aspire 直接运行 Web 项目时的数据库回退机制。1. Aspire Host 的定位与项目构成在 Clean.Architecture.slnx 解决方案中Clean.Architecture.AspireHost 是一个独立的 Aspire App Host 可执行项目负责编排应用及其所有依赖数据库、邮件服务器。其项目文件的关键配置如下Clean.Architecture.AspireHost.csprojProject SdkAspire.AppHost.Sdk/13.3.5 PropertyGroup OutputTypeExe/OutputType IsAspireHosttrue/IsAspireHost /PropertyGroup ItemGroup PackageReference IncludeAspire.Hosting.SqlServer / PackageReference IncludeMessagePack / /ItemGroup ItemGroup ProjectReference Include..\Clean.Architecture.Web\Clean.Architecture.Web.csproj / /ItemGroup ItemGroup !-- The IsAspireProjectResource attribute tells .NET Aspire to treat this reference as a standard project reference and not attempt to generate a metadata file -- ProjectReference Include..\Clean.Architecture.ServiceDefaults\Clean.Architecture.ServiceDefaults.csproj IsAspireProjectResourcefalse / /ItemGroup /Project几个要点IsAspireHosttrue加上Aspire.AppHost.Sdk使其成为 Aspire 编排入口编译产物为Exe通过Aspire.Hosting.SqlServer包获得 SQL Server 容器的类型化扩展AddSqlServer对 Clean.Architecture.Web 使用项目引用Aspire 会为其生成Projects.Clean_Architecture_Web访问器类型对 ServiceDefaults 项目标记IsAspireProjectResourcefalse按源码注释说明这是告诉 Aspire 以普通项目引用处理它不生成资源元数据文件。仓库根目录的 aspire.config.json 则声明了 app host 的路径让 Aspire 工具链能直接定位启动项目{ appHost: { path: src/Clean.Architecture.AspireHost/Clean.Architecture.AspireHost.csproj } }2. 资源图解析AppHost.cs 编排了哪些资源AppHost.cs 是整个编排的核心全文如下using System.Net.Sockets; var builder DistributedApplication.CreateBuilder(args); // Add SQL Server container var sqlServer builder.AddSqlServer(sqlserver) .WithLifetime(ContainerLifetime.Persistent); // Add the database var cleanArchDb sqlServer.AddDatabase(cleanarchitecture); // Papercut SMTP container for email testing var papercut builder.AddContainer(papercut, jijiechen/papercut, latest) .WithEndpoint(smtp, e { e.TargetPort 25; // container port e.Port 25; // host port e.Protocol ProtocolType.Tcp; e.UriScheme smtp; }) .WithEndpoint(ui, e { e.TargetPort 37408; e.Port 37408; e.UriScheme http; }); // Add the web project with the database connection builder.AddProjectProjects.Clean_Architecture_Web(web) .WithReference(cleanArchDb) .WithEnvironment(ASPNETCORE_ENVIRONMENT, builder.Environment.EnvironmentName) .WithEnvironment(Papercut__Smtp__Url, papercut.GetEndpoint(smtp)) .WaitFor(cleanArchDb) .WaitFor(papercut); builder .Build() .Run();从源码结构看资源图包含三类资源及其依赖关系SQL Server 容器资源名sqlserverAddSqlServer(sqlserver)创建一个 SQL Server 容器资源.WithLifetime(ContainerLifetime.Persistent)将生命周期设为持久化详见第 6 节。逻辑数据库资源名cleanarchitecturesqlServer.AddDatabase(cleanarchitecture)基于容器派生出一个数据库资源这是 Web 项目通过WithReference引用的对象。Papercut SMTP 容器使用jijiechen/papercut镜像Papercut 是带 Web 管理界面的 SMTP 邮件捕获/测试工具暴露两个端点smtp容器端口 25 映射到宿主机 25协议 TCPURI 方案smtp供应用发信ui端口 37408Papercut 的 Web 管理界面供人工查看收到的邮件。Web 项目资源名web通过AddProjectProjects.Clean_Architecture_Web(web)接入并施加了四项编排配置.WithReference(cleanArchDb)把cleanarchitecture数据库的连接信息注入 Web 进程以ConnectionStrings__cleanarchitecture环境变量形式提供即 README 中提到的连接字符串由 Aspire 自动提供.WithEnvironment(ASPNETCORE_ENVIRONMENT, builder.Environment.EnvironmentName)把宿主环境名透传给 Web保证环境配置一致.WithEnvironment(Papercut__Smtp__Url, papercut.GetEndpoint(smtp))注入 Papercut 的 SMTP 端点使 Web 的邮件发送配置MailserverConfiguration 绑定的Mailserver配置节默认localhost:25见 appsettings.json在 Aspire 编排下指向 Papercut 实例.WaitFor(cleanArchDb)与.WaitFor(papercut)声明启动顺序依赖Web 会等待数据库与 SMTP 就绪后再启动避免应用抢跑导致的连接失败。3. 运行应用以 Aspire Host 为启动项目README 给出的操作步骤与源码完全对应将Clean.Architecture.AspireHost设为启动项目运行应用F5 调试或 CtrlF5 不调试Aspire Dashboard 会自动打开展示所有运行中的资源包括 SQL Server 容器、Papercut 容器和 Web 应用Web 应用自动连接到 SQL Server 容器中的cleanarchitecture数据库。launchSettings.json 中预置了https与http两个启动配置文件。以默认的https配置为例{ profiles: { https: { commandName: Project, dotnetRunMessages: true, launchBrowser: true, applicationUrl: https://localhost:17143;http://localhost:15258, environmentVariables: { ASPNETCORE_ENVIRONMENT: Development, DOTNET_ENVIRONMENT: Development, DOTNET_DASHBOARD_OTLP_ENDPOINT_URL: https://localhost:21007, DOTNET_RESOURCE_SERVICE_ENDPOINT_URL: https://localhost:22245 } }, http: { commandName: Project, applicationUrl: http://localhost:15258, environmentVariables: { ASPNETCORE_ENVIRONMENT: Development, DOTNET_ENVIRONMENT: Development, DOTNET_DASHBOARD_OTLP_ENDPOINT_URL: http://localhost:19187, DOTNET_RESOURCE_SERVICE_ENDPOINT_URL: http://localhost:20134 } } } }applicationUrlAspire Host 自身暴露的端点资源服务监听地址DOTNET_DASHBOARD_OTLP_ENDPOINT_URL与DOTNET_RESOURCE_SERVICE_ENDPOINT_URLAspire Dashboard 的遥测与资源服务端口由 SDK 自动写入。appsettings.json 仅配置了日志级别并特意压低Aspire.Hosting.DcpDashboard Control Plane的日志到Warning减少启动期噪音{ Logging: { LogLevel: { Default: Information, Microsoft.AspNetCore: Warning, Aspire.Hosting.Dcp: Warning } } }另外仓库中的 AspireIntegrationTests 目前是占位测试工程为后续按 Aspire 官方测试指南补充宿主级集成测试预留了位置针对该编排链路的验证仍以功能/集成测试工程tests/Clean.Architecture.FunctionalTests 等为主。4. 连接字符串的注入与三级回退机制README 的关键论断是通过 Aspire 运行时连接字符串由 Aspire 自动提供会覆盖 appsettings.json 中的DefaultConnection连接名为 cleanarchitecture并被 Web 项目引用。这句话在源码中有明确的印证链。Web 项目的 appsettings.json 中定义了两条本地连接串{ ConnectionStrings: { // When running through Aspire, the connection string is provided automatically by the AspireHost // This DefaultConnection is used only when running the Web project directly on Windows (without Aspire) // You can configure this to point to your local SQL Server instance // Note: On Linux/macOS, this connection is skipped and SQLite is used instead DefaultConnection: Server(localdb)\\mssqllocaldb;Databasecleanarchitecture;Trusted_ConnectionTrue;MultipleActiveResultSetstrue, // SQLite is used as a fallback when running on Linux/macOS or when running standalone on Windows without Aspire SqliteConnection: Data Sourcedatabase.sqlite }, ... }而真正消费这些连接串的是 InfrastructureServiceExtensions.cs 中的注册逻辑// Try to get connection strings in order of priority: // 1. cleanarchitecture - provided by Aspire when using .WithReference(cleanArchDb) // 2. DefaultConnection - SQL Server (Windows only by default, can be forced with USE_SQL_SERVERtrue) // 3. SqliteConnection - fallback to SQLite bool isWindows OperatingSystem.IsWindows(); bool forceSqlServer Environment.GetEnvironmentVariable(USE_SQL_SERVER) true; string? connectionString config.GetConnectionString(cleanarchitecture) ?? ((isWindows || forceSqlServer) ? config.GetConnectionString(DefaultConnection) : null) ?? config.GetConnectionString(SqliteConnection); Guard.Against.Null(connectionString);可以归纳出一条三级优先级的选择链优先级连接串名称来源生效条件使用的 Provider1cleanarchitectureAspire 通过.WithReference(cleanArchDb)注入以 Aspire Host 启动时恒存在UseSqlServer2DefaultConnectionappsettings.jsonlocalDB 实例Windows 平台或显式设置环境变量USE_SQL_SERVERtrueUseSqlServer3SqliteConnectionappsettings.jsondatabase.sqlite文件上述条件均不满足时如 Linux/macOS 直接运行 WebUseSqlite即只要走 Aspire 编排注入的cleanarchitecture连接串必然排在第一位覆盖 appsettings.json 的效果由此实现数据库 Provider 的选择同样由这条链决定存在cleanarchitecture或满足条件的DefaultConnection时用 SQL Server否则回退 SQLite。5. 不经过 Aspire 直接运行 Web 项目时的行为README 说明直接运行 Web 项目不经过 AspireHost时会回退使用 appsettings.json 中的 SQLite 连接串。结合第 4 节的选择链实际行为是Linux / macOS上直接运行 Webcleanarchitecture不存在且非 Windows 平台不会取DefaultConnection因此最终使用SqliteConnectionData Sourcedatabase.sqlite。Windows上直接运行 Web优先取DefaultConnectionlocalDB 的 SQL Server 实例若不存在该连接串例如被移除仍会继续回退到 SQLite。在任意平台上设置环境变量USE_SQL_SERVERtrue可以强制在非 Windows 环境走DefaultConnection的 SQL Server 路径——这是对容器化或 CI 场景的一个逃生舱。数据库初始化行为由 MiddlewareConfig.cs 中的启动中间件控制在 Development 环境或Database:ApplyMigrationsOnStartup为true时自动执行迁移并填充种子数据SeedData。其中对 SQLite 采用EnsureCreatedAsync()建库本地开发常见做法对 SQL Server 执行MigrateAsync()。因此 README 中通过 Aspire 运行时若数据库不存在会自动在 SQL Server 容器内创建的说法本质上是 Aspire 负责建库 Web 启动时自动迁移二者配合的结果。测试环境另有 appsettings.Testing.json将SqliteConnection覆盖为:memory:供功能测试使用内存库。6. 创建迁移与更新数据库EF Core CLIREADME 明确说明现有迁移为 SQLite 创建同样兼容 SQL Server。以下命令均在Web 项目目录下执行因为启动项目-s必须是能构建出AppDbContext的 Web 项目而上下文本身定义在 Infrastructure 项目-p指定其 csproj创建新迁移dotnet ef migrations add MigrationName -c AppDbContext -p ../Clean.Architecture.Infrastructure/Clean.Architecture.Infrastructure.csproj -s Clean.Architecture.Web.csproj -o Data/Migrations更新数据库dotnet ef database update -c AppDbContext -p ../Clean.Architecture.Infrastructure/Clean.Architecture.Infrastructure.csproj -s Clean.Architecture.Web.csproj参数说明-c AppDbContext目标上下文类型 AppDbContext-p ../Clean.Architecture.Infrastructure/Clean.Architecture.Infrastructure.csproj包含上下文的项目-s Clean.Architecture.Web.csproj启动项目提供 DI 与配置来源-o Data/Migrations迁移输出目录对应现有的 Data/Migrations 目录含初始迁移及 UseDbGeneratedIds 等后续迁移。需要留意的一点通过 Aspire 运行时Web 进程中的连接串指向 SQL Server 容器CLI 命令若在同目录执行、读取同样的 appsettings其实际连接的数据库取决于当时环境中的连接串解析结果建议在与目标一致的运行环境下执行迁移操作。7. 容器持久化与数据库重置README 最后一段指出SQL Server 容器配置为ContainerLifetime.Persistent数据会在应用多次运行之间保留。对应 AppHost.cs 中的var sqlServer builder.AddSqlServer(sqlserver) .WithLifetime(ContainerLifetime.Persistent);Persistent生命周期意味着 Aspire 在应用停止后不会删除该容器SQL Server 中的数据卷得以跨运行保留。对比之下若使用默认的FixedInterval或Once生命周期容器会随宿主进程退出而被清理。重置数据库丢弃持久化数据的两种方式摘自 README在 Aspire Dashboard 中删除该容器使用 Docker CLIdocker rm container-name容器名以 Dashboard 中显示的资源名为准。删除后再次启动 Aspire Host容器会按镜像与持久化策略重新创建Web 启动时的自动迁移会重新初始化数据库结构。8. 小结这套编排方案的可复制要点从 src/Clean.Architecture.AspireHost 目录可以提炼出在 Clean Architecture 分层解决方案中引入 Aspire 的几个模式编排入口独立成项目App Host 只依赖被编排项目Web与 ServiceDefaults不承载业务代码用AddDatabase派生逻辑数据库再通过WithReference把连接字符串以ConnectionStrings__cleanarchitecture形式注入应用让应用侧以连接串名称而非具体连接串编程应用侧保留多级回退Aspire 注入 → 本地 SQL Server → SQLite使走 Aspire与直接跑 Web两种开发方式都能开箱即用且互不冲突WaitFor显式声明启动依赖配合 Web 启动时的自动迁移与种子数据省去手工建库步骤ContainerLifetime.Persistent Dashboard/Docker 重置流程兼顾开发期数据连续性与可复现性Papercut SMTP 容器让领域事件的邮件通知链路如 IEmailSender 的 SMTP 实现 MimeKitEmailSender在本地也有可验证的闭环——发件可经smtp端点收件可经 37408 端点的 Web 界面查看。【免费下载链接】CleanArchitectureClean Architecture Solution Template: A proven Clean Architecture Template for ASP.NET Core 10项目地址: https://gitcode.com/GitHub_Trending/cl/CleanArchitecture创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表