.NET 6 中配置数据库上下文和服务的完整指南
.NET 6 引入了重大的架构变化,将传统的 Startup.cs
和 Program.cs
文件合并为一个简化的 Program.cs
文件。本文将详细介绍如何在这一变化中配置数据库上下文和各种服务。
重要变化
从 .NET 6 开始,Microsoft 移除了单独的 Startup.cs
类,所有配置现在都在 Program.cs
中完成
基本的 Program.cs 配置
csharp
var builder = WebApplication.CreateBuilder(args);
// 添加数据库上下文
builder.Services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(builder.Configuration.GetConnectionString("DefaultConnection")));
var app = builder.Build();
// 中间件配置...
app.Run();
完整的配置示例
以下是一个完整的 Program.cs
配置示例,包含了数据库上下文、身份认证、Swagger 等常见配置:
csharp
using Microsoft.EntityFrameworkCore;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.IdentityModel.Tokens;
using System.Text;
var builder = WebApplication.CreateBuilder(args);
// 数据库上下文配置
builder.Services.AddDbContext<BookStoreContext>(options =>
options.UseSqlServer(builder.Configuration.GetConnectionString("BookStoreDB")));
// 控制器和 API 配置
builder.Services.AddControllers().AddNewtonsoftJson();
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
// 身份认证配置
builder.Services.AddIdentity<ApplicationUser, IdentityRole>()
.AddEntityFrameworkStores<BookStoreContext>()
.AddDefaultTokenProviders();
// JWT 配置
builder.Services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
}).AddJwtBearer(option =>
{
option.SaveToken = true;
option.RequireHttpsMetadata = false;
option.TokenValidationParameters = new TokenValidationParameters()
{
ValidateIssuer = true,
ValidateAudience = true,
ValidAudience = builder.Configuration["JWT:ValidAudience"],
ValidIssuer = builder.Configuration["JWT:ValidIssuer"],
IssuerSigningKey = new SymmetricSecurityKey(
Encoding.UTF8.GetBytes(builder.Configuration["JWT:Secret"]))
};
});
// 自定义服务注册
builder.Services.AddTransient<IBookRepository, BookRepository>();
builder.Services.AddTransient<IAccountRepository, AccountRepository>();
// CORS 配置
builder.Services.AddCors(option =>
{
option.AddDefaultPolicy(builder =>
{
builder.AllowAnyOrigin().AllowAnyHeader().AllowAnyMethod();
});
});
var app = builder.Build();
// 开发环境配置
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
}
app.UseHttpsRedirection();
app.UseRouting();
app.UseCors();
app.UseAuthentication();
app.UseAuthorization();
app.MapControllers();
app.Run();
扩展方法模式(推荐)
为了保持代码的整洁和可维护性,推荐使用扩展方法模式:
csharp
// HostingExtensions.cs
public static class HostingExtensions
{
public static WebApplication ConfigureServices(this WebApplicationBuilder builder)
{
// 服务配置
builder.Services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(builder.Configuration.GetConnectionString("DefaultConnection")));
builder.Services.AddControllers();
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
return builder.Build();
}
public static WebApplication ConfigurePipeline(this WebApplication app)
{
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
}
app.UseHttpsRedirection();
app.UseAuthorization();
app.MapControllers();
return app;
}
}
// Program.cs
var builder = WebApplication.CreateBuilder(args);
builder.ConfigureServices().ConfigurePipeline().Run();
传统的 Startup 类方式
如果你更喜欢传统的 Startup.cs
模式,也可以手动重新创建:
csharp
// Startup.cs
public class Startup
{
public IConfiguration Configuration { get; }
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
services.AddControllersWithViews();
}
public void Configure(WebApplication app, IWebHostEnvironment env)
{
if (!env.IsDevelopment())
{
app.UseExceptionHandler("/Home/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthorization();
app.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
}
}
// Program.cs
var builder = WebApplication.CreateBuilder(args);
var startup = new Startup(builder.Configuration);
startup.ConfigureServices(builder.Services);
var app = builder.Build();
startup.Configure(app, app.Environment);
app.Run();
注意事项
- 确保
appsettings.json
中包含正确的连接字符串配置 - 数据库上下文的命名空间需要正确导入
- 中间件的顺序很重要(如
UseRouting
必须在UseAuthorization
之前)
服务注册的不同方式
在 .NET 6 中,服务的注册方式与之前类似,只是位置发生了变化:
csharp
// 瞬态服务(每次请求都创建新实例)
builder.Services.AddTransient<IEmailService, EmailService>();
// 作用域服务(每个请求一个实例)
builder.Services.AddScoped<IUserService, UserService>();
// 单例服务(整个应用生命周期一个实例)
builder.Services.AddSingleton<ICacheService, CacheService>();
总结
.NET 6 的简化编程模型使得应用程序配置更加简洁明了。虽然失去了传统的 Startup.cs
分离结构,但获得了更紧凑的代码布局。你可以根据项目需求选择直接在 Program.cs
中配置,使用扩展方法保持代码整洁,或者重新创建传统的 Startup
类结构。
迁移提示
从 .NET 5 迁移到 .NET 6 时,只需将 Startup.cs
中的内容移动到 Program.cs
,并将 services
替换为 builder.Services
即可完成大部分迁移工作。