微服务架构 C# 入门
微服务架构(MSA)是一种软件开发方法,它将应用程序构建为一组小型、可独立部署的服务。每个服务实现一个业务功能,拥有自己的数据库,并且可以用不同的语言编写。然而,在 .NET 生态系统中,C# 和 ASP.NET Core 提供了构建可靠微服务的最佳工具之一。
在本文中,我们将介绍使用 C# 创建微服务的完整周期:从架构设计到容器化部署。您将了解如何组织服务之间的交互,确保其容错性和可扩展性。
1. 基于 .NET 的微服务架构设计
第一步是将单体应用正确地拆分为服务。一个好的实践是遵循 领域驱动设计(DDD) 原则,并识别出 限界上下文(Bounded Contexts)。
1.1. 定义服务边界
每个微服务应负责一个业务实体或流程。例如,对于在线商店,可以划分出:
- Catalog Service — 商品管理
- Order Service — 订单处理
- Payment Service — 支付
- Notification Service — 通知
重要提示:每个服务拥有 自己的数据库。这可以防止耦合,并允许独立地扩展服务。
1.2. ASP.NET Core 项目结构
一个典型的 C# 微服务由多个层组成:
- API Layer — 控制器和中间件
- Application Layer — CQRS、MediatR、命令和查询
- Domain Layer — 实体、值对象、聚合
- Infrastructure Layer — 仓储、DbContext、外部服务
最小目录结构示例:
MyMicroservice/
├── MyMicroservice.Api/
│ └── Controllers/
├── MyMicroservice.Application/
│ └── Commands/
├── MyMicroservice.Domain/
│ └── Entities/
└── MyMicroservice.Infrastructure/
└── Data/
2. C# 微服务实现:实践示例
我们将使用 ASP.NET Core 8 和 Entity Framework Core 创建一个简单的商品目录管理服务。
2.1. 配置 WebApplication
在 Program.cs 文件中配置最小 API:
var builder = WebApplication.CreateBuilder(args);
// 添加服务
builder.Services.AddDbContext<CatalogDbContext>(options =>
options.UseSqlServer(builder.Configuration.GetConnectionString("CatalogDb")));
builder.Services.AddMediatR(cfg => cfg.RegisterServicesFromAssembly(typeof(Program).Assembly));
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
var app = builder.Build();
// 中间件
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
}
app.UseHttpsRedirection();
// 最小 API 端点
app.MapGet("/api/products", async (IMediator mediator) =>
{
var products = await mediator.Send(new GetProductsQuery());
return Results.Ok(products);
});
app.Run();
2.2. 数据模型与 CQRS
创建 Product 实体:
public class Product
{
public Guid Id { get; set; }
public string Name { get; set; } = string.Empty;
public decimal Price { get; set; }
public string Category { get; set; } = string.Empty;
}
使用 MediatR 实现 CQRS 模式来分离命令和查询:
public record GetProductsQuery() : IRequest<List<Product>>;
public class GetProductsHandler : IRequestHandler<GetProduc
```