Skip to content
Go back

【ASP.NET Core】用ServiceCollection Extension Pattern简化服务注册,提升代码质量!

【ASP.NET Core】用ServiceCollection Extension Pattern简化服务注册,提升代码质量!

🎯 在现代软件开发中,代码的组织性和可维护性至关重要,尤其是对于复杂的后端应用而言。今天我们将探讨一种能有效提升代码质量的设计模式——ServiceCollection Extension Pattern,这一模式可以让你的服务注册逻辑更加清晰高效,并且能够轻松应对复杂应用场景。


什么是Dependency Injection(DI)?

在.NET环境中,Dependency Injection(DI)是一个非常重要的技术,它不仅能让你的代码更加灵活和可测试,还可以实现松耦合设计。🎯 DI是控制反转(IoC)原则的具体体现,它将对象创建的控制权交给容器或框架,而不是由类本身去负责。

在ASP.NET Core中,IServiceCollection接口承担了服务注册的关键角色,它允许开发者添加、移除和检索服务。通常,我们会在Program.cs文件中进行这些操作。然而,当项目规模逐渐扩大时,Program.cs会变得越来越杂乱。这时,ServiceCollection Extension Pattern就派上了用场。


什么是ServiceCollection Extension Pattern?

✨ ServiceCollection Extension Pattern是一种优化服务注册逻辑的设计模式。它通过将服务注册封装到静态扩展方法中,使代码结构更加整洁,同时提高可维护性。

示例代码

以下是一个简单的扩展方法示例:

public static class ServiceCollectionExtensions
{
    public static IServiceCollection AddCustomServices(
        this IServiceCollection services)
    {
        services.AddScoped<IMyService, MyService>();
        services.AddSingleton<IOtherService, OtherService>();

        // ... 注册更多服务

        return services;
    }
}

Program.cs中,我们可以直接调用这个扩展方法:

builder.Services.AddCustomServices();

通过这种方式,服务注册逻辑被抽离到了单独的静态类中,让Program.cs文件更加简洁。


实际应用场景

💡 在真实项目中,我们可以根据服务类型或应用层次进一步分类这些扩展方法。例如,在一个使用Entity Framework Core和身份认证功能的ASP.NET Core项目中,我们可以分别创建以下扩展方法:

数据库服务注册

public static IServiceCollection AddDatabase(
    this IServiceCollection services,
    string connectionString)
{
    services.AddDbContext<MyDbContext>(options => options.UseSqlServer(connectionString));
    return services;
}

身份认证服务注册

public static IServiceCollection AddIdentityServices(
    this IServiceCollection services)
{
    services.AddIdentity<ApplicationUser, IdentityRole>()
        .AddEntityFrameworkStores<MyDbContext>()
        .AddDefaultTokenProviders();
    return services;
}

JWT认证服务注册

public static IServiceCollection AddJwtAuthentication(
    this IServiceCollection services, IConfiguration configuration)
{
    var jwtSettings = configuration.GetSection("JwtSettings");
    var key = Encoding.ASCII.GetBytes(jwtSettings.GetValue<string>("Secret"));

    services.AddAuthentication(options =>
    {
        options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
        options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
    })
    .AddJwtBearer(options =>
    {
        options.RequireHttpsMetadata = false;
        options.SaveToken = true;
        options.TokenValidationParameters = new TokenValidationParameters
        {
            ValidateIssuerSigningKey = true,
            IssuerSigningKey = new SymmetricSecurityKey(key),
            ValidateIssuer = false,
            ValidateAudience = false
        };
    });

    return services;
}

CORS策略配置

public static IServiceCollection AddCorsPolicy(
    this IServiceCollection services,
    string policyName,
    string[] allowedOrigins)
{
    services.AddCors(options =>
    {
        options.AddPolicy(policyName,
            builder => builder.WithOrigins(allowedOrigins)
                     .AllowAnyMethod()
                     .AllowAnyHeader()
                     .AllowCredentials());
    });

    return services;
}

Program.cs中,我们可以统一调用这些扩展方法:

builder.Services.AddDatabase(Configuration.GetConnectionString("DefaultConnection"));
builder.Services.AddIdentityServices();
builder.Services.AddJwtAuthentication(Configuration);
builder.Services.AddCorsPolicy("MyPolicy", new[] { "http://example.com" });

// ... 其他配置

为什么要使用它?

采用ServiceCollection Extension Pattern,你可以获得以下优势:

1. 提高代码组织性和可读性 📚

通过将服务注册逻辑抽离到扩展方法中,你可以保持Program.cs的简洁性,同时快速理解每个服务的功能。

2. 封装复杂性 🔒

封装服务注册逻辑使其他部分的代码不需要关心其细节,从而增强模块化设计。

3. 提升可维护性 🔧

当项目需求发生变化时,你只需在对应的扩展方法中修改相关逻辑,无需在Program.cs中查找并修改冗长的代码块。

4. 增强重用性 ♻️

如果多个项目共享相似的服务注册逻辑,你可以将这些扩展方法打包成库,方便跨项目使用。


总结

🎉 ServiceCollection Extension Pattern是一种让你的ASP.NET Core项目更简洁、更高效的设计模式。通过将服务注册逻辑分离到独立的静态类,你可以显著提升代码的组织性、可读性和可维护性,同时为团队协作提供更清晰的结构。

💡 如果你正在开发一个中大型项目,不妨试试这个模式,相信它会为你的代码质量带来飞跃式提升!


📢 喜欢这篇文章吗?记得点赞、分享给你的朋友或者团队!如果你有任何疑问或建议,请在评论区留言,我们一起交流学习! 😊


标签


Previous Post
在.NET 9中打造自定义GraphQL查询构建器:最佳实践与完整实现
Next Post
从领域事件到松耦合系统:如何用EF Core和MediatR构建高效架构