基础设施层与Web层架构设计:数据持久化与API端点实现

基础设施层与Web层架构设计:数据持久化与API端点实现

【免费下载链接】CleanArchitecture Jason Taylor开发的Clean Architecture项目模板同样基于.NET Core,遵循干净架构原则。它提供了一种组织代码结构的良好起点,鼓励面向接口编程和关注点分离,适用于需要长期维护和易于扩展的企业级应用程序开发。 【免费下载链接】CleanArchitecture 项目地址: https://gitcode.com/gh_mirrors/cle/CleanArchitecture

本文深入探讨了Clean Architecture模板中基础设施层与Web层的架构设计与实现细节。在基础设施层,重点分析了Entity Framework Core的数据访问配置,包括DbContext设计、Fluent API实体映射、审计拦截器机制和多数据库支持策略。同时详细介绍了ASP.NET Core Identity服务的集成方式,包括用户认证授权架构、声明式授权管道和API端点自动映射。在Web层,阐述了基于Minimal API的端点组架构设计,包括强类型结果返回、依赖注入与MediatR集成、以及自动端点发现机制。最后,系统讲解了分层依赖注入配置策略和基于MediatR的跨层通信机制,展示了如何通过管道行为处理横切关注点,实现各层之间的松耦合通信。

Infrastructure层数据访问与EF Core配置

在现代企业级应用开发中,数据访问层的设计质量直接影响着系统的可维护性、扩展性和性能表现。CleanArchitecture项目通过精心设计的Infrastructure层,展示了如何基于Entity Framework Core构建健壮的数据访问基础设施。本文将深入探讨该层的关键实现细节,包括DbContext配置、实体映射、拦截器机制以及数据库初始化策略。

核心DbContext设计与实现

ApplicationDbContext作为数据访问的核心枢纽,继承自IdentityDbContext并实现了IApplicationDbContext接口,完美融合了身份认证与业务数据访问功能:

public class ApplicationDbContext : IdentityDbContext<ApplicationUser>, IApplicationDbContext
{
    public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options) : base(options) { }

    public DbSet<TodoList> TodoLists => Set<TodoList>();
    public DbSet<TodoItem> TodoItems => Set<TodoItem>();

    protected override void OnModelCreating(ModelBuilder builder)
    {
        base.OnModelCreating(builder);
        builder.ApplyConfigurationsFromAssembly(Assembly.GetExecutingAssembly());
    }
}

这种设计遵循了接口隔离原则,通过IApplicationDbContext接口向应用层暴露必要的DbSet属性,同时隐藏了EF Core的具体实现细节。

实体配置与Fluent API映射

项目采用Fluent API方式进行实体配置,通过独立的配置类实现关注点分离。以TodoListConfiguration为例:

public class TodoListConfiguration : IEntityTypeConfiguration<TodoList>
{
    public void Configure(EntityTypeBuilder<TodoList> builder)
    {
        builder.Property(t => t.Title)
            .HasMaxLength(200)
            .IsRequired();

        builder.OwnsOne(b => b.Colour);
    }
}

这种配置方式提供了以下优势:

  • 类型安全:编译时检查配置的正确性
  • 可维护性:每个实体拥有独立的配置类
  • 可扩展性:易于添加新的配置规则

依赖注入与DbContext配置

Infrastructure层通过扩展方法提供完整的依赖注入配置:

mermaid

关键配置代码展示了多数据库支持策略:

builder.Services.AddDbContext<ApplicationDbContext>((sp, options) =>
{
    options.AddInterceptors(sp.GetServices<ISaveChangesInterceptor>());
#if (UsePostgreSQL)
    options.UseNpgsql(connectionString);
#elif (UseSqlite)
    options.UseSqlite(connectionString);
#else
    options.UseSqlServer(connectionString);
#endif
    options.ConfigureWarnings(warnings => warnings.Ignore(RelationalEventId.PendingModelChangesWarning));
});

审计拦截器机制

AuditableEntityInterceptor实现了自动审计跟踪功能,自动记录实体的创建和修改信息:

public override ValueTask<InterceptionResult<int>> SavingChangesAsync(
    DbContextEventData eventData, 
    InterceptionResult<int> result, 
    CancellationToken cancellationToken = default)
{
    UpdateEntities(eventData.Context);
    return base.SavingChangesAsync(eventData, result, cancellationToken);
}

private void UpdateEntities(DbContext? context)
{
    foreach (var entry in context.ChangeTracker.Entries<BaseAuditableEntity>())
    {
        if (entry.State is EntityState.Added or EntityState.Modified)
        {
            var utcNow = _dateTime.GetUtcNow();
            if (entry.State == EntityState.Added)
            {
                entry.Entity.CreatedBy = _user.Id;
                entry.Entity.Created = utcNow;
            } 
            entry.Entity.LastModifiedBy = _user.Id;
            entry.Entity.LastModified = utcNow;
        }
    }
}

数据库初始化策略

ApplicationDbContextInitialiser提供了灵活的数据库初始化方案:

mermaid

初始化过程包含三个关键阶段:

  1. 数据库清理与创建:使用EnsureDeleted和EnsureCreated方法
  2. 角色与用户种子数据:创建默认管理员角色和用户
  3. 业务数据种子:插入示例TodoList数据

配置最佳实践总结

通过分析CleanArchitecture项目的Infrastructure层,我们可以总结出以下EF Core配置最佳实践:

实践领域实现方式优势
DbContext设计继承IdentityDbContext + 接口实现身份集成 + 接口隔离
实体配置独立的IEntityTypeConfiguration类关注点分离 + 可维护性
依赖注入扩展方法封装配置集中化 + 易于测试
审计跟踪SaveChangesInterceptor自动化 + 非侵入式
多数据库支持编译指令条件编译环境适配 + 灵活性
数据种子独立的Initialiser类可控性 + 可测试性

这种架构设计确保了数据访问层的健壮性和可扩展性,为上层应用提供了稳定可靠的数据持久化基础设施。通过拦截器模式、接口隔离和配置分离等技术的综合运用,实现了高度可维护和可测试的数据访问解决方案。

Identity服务集成与用户认证授权

在现代企业级应用开发中,用户认证与授权是保障系统安全的核心机制。Clean Architecture模板通过ASP.NET Core Identity框架提供了完整的身份管理解决方案,同时遵循干净架构原则,将认证授权逻辑与业务逻辑清晰分离。

Identity服务架构设计

Clean Architecture中的Identity服务采用分层架构设计,通过接口抽象和依赖注入实现松耦合:

mermaid

核心组件实现

1. Identity服务接口与实现

项目定义了IIdentityService接口作为身份服务的契约,由基础设施层的IdentityService类具体实现:

// 应用层接口定义
public interface IIdentityService
{
    Task<string?> GetUserNameAsync(string userId);
    Task<bool> IsInRoleAsync(string userId, string role);
    Task<bool> AuthorizeAsync(string userId, string policyName);
    Task<(Result Result, string UserId)> CreateUserAsync(string userName, string password);
    Task<Result> DeleteUserAsync(string userId);
}

// 基础设施层实现
public class IdentityService : IIdentityService
{
    private readonly UserManager<ApplicationUser> _userManager;
    private readonly IUserClaimsPrincipalFactory<ApplicationUser> _userClaimsPrincipalFactory;
    private readonly IAuthorizationService _authorizationService;

    public async Task<bool> AuthorizeAsync(string userId, string policyName)
    {
        var user = await _userManager.FindByIdAsync(userId);
        if (user == null) return false;

        var principal = await _userClaimsPrincipalFactory.CreateAsync(user);
        var result = await _authorizationService.AuthorizeAsync(principal, policyName);
        return result.Succeeded;
    }
}
2. 用户实体与角色管理

项目扩展了ASP.NET Core Identity的默认用户实体,并预定义了系统角色:

// 自定义用户实体
public class ApplicationUser : IdentityUser
{
    // 可根据业务需求添加自定义属性
}

// 系统角色常量
public abstract class Roles
{
    public const string Administrator = nameof(Administrator);
}

// 授权策略常量
public abstract class Policies
{
    public const string CanPurge = nameof(CanPurge);
}

认证授权配置

在基础设施层的依赖注入配置中,项目设置了完整的Identity服务:

public static void AddInfrastructureServices(this IHostApplicationBuilder builder)
{
    // API Only模式配置
    builder.Services.AddAuthentication()
        .AddBearerToken(IdentityConstants.BearerScheme);

    builder.Services.AddAuthorizationBuilder();

    builder.Services
        .AddIdentityCore<ApplicationUser>()
        .AddRoles<IdentityRole>()
        .AddEntityFrameworkStores<ApplicationDbContext>()
        .AddApiEndpoints();

    // 传统MVC模式配置
    builder.Services
        .AddDefaultIdentity<ApplicationUser>()
        .AddRoles<IdentityRole>()
        .AddEntityFrameworkStores<ApplicationDbContext>();

    // 注册自定义身份服务
    builder.Services.AddTransient<IIdentityService, IdentityService>();

    // 配置授权策略
    builder.Services.AddAuthorization(options =>
        options.AddPolicy(Policies.CanPurge, policy => policy.RequireRole(Roles.Administrator)));
}

授权行为管道

项目通过MediatR管道行为实现了声明式授权,自动处理所有请求的授权验证:

mermaid

授权行为的具体实现:

public class AuthorizationBehaviour<TRequest, TResponse> : IPipelineBehavior<TRequest, TResponse>
{
    public async Task<TResponse> Handle(TRequest request, RequestHandlerDelegate<TResponse> next, CancellationToken cancellationToken)
    {
        var authorizeAttributes = request.GetType().GetCustomAttributes<AuthorizeAttribute>();

        if (authorizeAttributes.Any())
        {
            // 必须认证用户
            if (_user.Id == null) throw new UnauthorizedAccessException();

            // 角色基础授权
            var authorizeAttributesWithRoles = authorizeAttributes.Where(a => !string.IsNullOrWhiteSpace(a.Roles));
            if (authorizeAttributesWithRoles.Any() && !IsInAnyRole(authorizeAttributesWithRoles))
                throw new ForbiddenAccessException();

            // 策略基础授权
            var authorizeAttributesWithPolicies = authorizeAttributes.Where(a => !string.IsNullOrWhiteSpace(a.Policy));
            foreach (var policy in authorizeAttributesWithPolicies.Select(a => a.Policy))
            {
                var authorized = await _identityService.AuthorizeAsync(_user.Id, policy);
                if (!authorized) throw new ForbiddenAccessException();
            }
        }

        return await next();
    }
}

声明式授权使用

在应用层使用声明式授权注解来控制访问权限:

// 需要认证的用户
[Authorize]
public class GetTodos : IRequest<TodosVm> { }

// 需要管理员角色
[Authorize(Roles = Roles.Administrator)]
public class PurgeTodoLists : IRequest { }

// 需要特定策略
[Authorize(Policy = Policies.CanPurge)]
public class PurgeTodoLists : IRequest { }

API端点集成

对于Web API项目,模板提供了Identity API端点的自动映射:

public class Users : EndpointGroupBase
{
    public override void Map(WebApplication app)
    {
        app.MapGroup(this)
            .MapIdentityApi<ApplicationUser>();
    }
}

这自动提供了以下RESTful端点:

HTTP方法端点路径功能描述
POST/register用户注册
POST/login用户登录
POST/refresh刷新令牌
GET/manage/info获取用户信息
POST/manage/info更新用户信息

错误处理与结果转换

项目提供了Identity结果到应用层结果的转换扩展:

public static class IdentityResultExtensions
{
    public static Result ToApplicationResult(this IdentityResult result)
    {
        return result.Succeeded
            ? Result.Success()
            : Result.Failure(result.Errors.Select(e => e.Description));
    }
}

这种设计确保了Identity服务的错误信息能够以统一的格式返回给客户端,保持了整个应用的一致性错误处理机制。

通过这种分层架构设计,Clean Architecture模板实现了高度可测试、可维护的身份认证授权系统,既利用了ASP.NET Core Identity的强大功能,又保持了架构的清晰性和灵活性。

Web层端点设计与Minimal API实现

在现代ASP.NET Core应用程序开发中,Minimal API提供了一种简洁而强大的方式来构建HTTP API端点。Clean Architecture模板通过精心设计的端点架构,将Minimal API的优势与干净架构原则完美结合,实现了高度模块化和可维护的Web层设计。

端点组架构设计

Clean Architecture采用基于组的端点组织方式,通过EndpointGroupBase抽象基类为所有端点提供统一的编程模型:

public abstract class EndpointGroupBase
{
    public virtual string? GroupName { get; }
    public abstract void Map(RouteGroupBuilder groupBuilder);
}

这种设计允许每个功能模块(如TodoLists、TodoItems等)拥有自己独立的端点组,每个组负责映射相关的HTTP端点。以下是一个典型的端点组实现示例:

public class TodoLists : EndpointGroupBase
{
    public override void Map(RouteGroupBuilder groupBuilder)
    {
        groupBuilder.MapGet(GetTodoLists).RequireAuthorization();
        groupBuilder.MapPost(CreateTodoList).RequireAuthorization();
        groupBuilder.MapPut(UpdateTodoList, "{id}").RequireAuthorization();
        groupBuilder.MapDelete(DeleteTodoList, "{id}").RequireAuthorization();
    }
    
    // 具体的端点处理方法
    public async Task<Ok<TodosVm>> GetTodoLists(ISender sender)
    {
        var vm = await sender.Send(new GetTodosQuery());
        return TypedResults.Ok(vm);
    }
}

扩展方法简化端点映射

项目提供了强大的扩展方法集来简化端点映射过程,这些方法封装了常见的映射模式并提供了额外的功能:

public static RouteHandlerBuilder MapGet(this IEndpointRouteBuilder builder, 
    Delegate handler, [StringSyntax("Route")] string pattern = "")
{
    Guard.Against.AnonymousMethod(handler);
    return builder.MapGet(pattern, handler).WithName(handler.Method.Name);
}

这些扩展方法不仅简化了代码,还提供了以下优势:

  • 自动端点命名(基于处理方法名称)
  • 防止匿名方法的使用
  • 统一的错误处理模式
  • 一致的授权配置

强类型结果返回

Minimal API支持强类型的返回结果,这提供了更好的类型安全和API文档生成:

public async Task<Created<int>> CreateTodoList(ISender sender, CreateTodoListCommand command)
{
    var id = await sender.Send(command);
    return TypedResults.Created($"/{nameof(TodoLists)}/{id}", id);
}

public async Task<Results<NoContent, BadRequest>> UpdateTodoList(
    ISender sender, int id, UpdateTodoListCommand command)
{
    if (id != command.Id) return TypedResults.BadRequest();
    await sender.Send(command);
    return TypedResults.NoContent();
}

端点注册与发现

在应用程序启动时,通过MapEndpoints扩展方法自动发现并注册所有端点组:

mermaid

这种自动发现机制确保了新的端点组只需继承EndpointGroupBase即可自动注册,无需手动修改启动代码。

路由组与版本控制

端点组天然支持路由分组,为未来的API版本控制提供了良好的基础架构:

// 当前实现
groupBuilder.MapGet(GetTodoLists).RequireAuthorization();

// 未来可扩展为版本化路由
groupBuilder.MapGet(GetTodoLists, "v1/todos").RequireAuthorization();

安全与授权集成

所有端点都集成了ASP.NET Core的授权系统,通过RequireAuthorization()方法确保只有经过认证的用户才能访问受保护的端点:

groupBuilder.MapGet(GetTodoLists).RequireAuthorization();
groupBuilder.MapPost(CreateTodoList).RequireAuthorization();

依赖注入与MediatR集成

端点处理方法通过依赖注入接收ISender接口,用于发送命令和查询到应用层:

public async Task<Ok<TodosVm>> GetTodoLists(ISender sender)
{
    var vm = await sender.Send(new GetTodosQuery());
    return TypedResults.Ok(vm);
}

这种设计保持了端点的简洁性,同时充分利用了MediatR的中间件管道来处理横切关注点,如验证、日志和异常处理。

错误处理与验证

端点设计包含了完善的错误处理机制,通过强类型结果返回适当的HTTP状态码:

HTTP方法成功状态码错误状态码使用场景
GET200 OK401 Unauthorized获取资源列表
POST201 Created400 BadRequest创建新资源
PUT204 NoContent400 BadRequest更新资源
DELETE204 NoContent404 NotFound删除资源

性能优化考虑

Minimal API的设计天然具有性能优势,相比传统的Controller-based API,它具有:

  1. 更低的内存开销:减少了Controller实例化的开销
  2. 更快的路由匹配:简化的路由结构提高了匹配速度
  3. 减少的中间件层:更直接的请求处理管道
  4. 更好的预热性能:更少的JIT编译时间

测试友好设计

端点设计考虑了可测试性,每个端点处理方法都是独立的静态方法,便于单元测试:

// 易于测试的端点方法
public static async Task<Ok<TodosVm>> GetTodoLists(ISender sender)
{
    var vm = await sender.Send(new GetTodosQuery());
    return TypedResults.Ok(vm);
}

扩展性与维护性

当前的端点架构为未来的扩展提供了良好的基础:

  • 支持OpenAPI/Swagger集成:通过方法命名自动生成API文档
  • 支持API版本控制:路由组结构便于添加版本前缀
  • 支持速率限制:可轻松添加限流中间件
  • 支持缓存策略:可配置响应缓存头

通过这种精心设计的Minimal API实现,Clean Architecture模板提供了一个既符合现代Web开发最佳实践,又保持干净架构原则的高质量Web层解决方案。

依赖注入配置与跨层通信机制

在Clean Architecture模板中,依赖注入(DI)和跨层通信机制是实现松耦合架构的核心技术。该模板采用了现代化的DI配置方式和基于MediatR的CQRS模式,确保了各层之间的清晰边界和高效通信。

分层依赖注入配置

Clean Architecture模板采用了分层的依赖注入配置策略,每个层都提供了自己的DependencyInjection扩展方法:

// Web层Program.cs中的DI配置
var builder = WebApplication.CreateBuilder(args);
builder.AddKeyVaultIfConfigured();
builder.AddApplicationServices();    // 应用层服务
builder.AddInfrastructureServices(); // 基础设施层服务  
builder.AddWebServices();            // Web层服务
应用层服务注册

应用层主要负责注册MediatR、AutoMapper和FluentValidation等核心组件:

public static void AddApplicationServices(this IHostApplicationBuilder builder)
{
    builder.Services.AddAutoMapper(Assembly.GetExecutingAssembly());
    builder.Services.AddValidatorsFromAssembly(Assembly.GetExecutingAssembly());
    
    builder.Services.AddMediatR(cfg => {
        cfg.RegisterServicesFromAssembly(Assembly.GetExecutingAssembly());
        cfg.AddOpenRequestPreProcessor(typeof(LoggingBehaviour<>));
        cfg.AddOpenBehavior(typeof(UnhandledExceptionBehaviour<,>));
        cfg.AddOpenBehavior(typeof(AuthorizationBehaviour<,>));
        cfg.AddOpenBehavior(typeof(ValidationBehaviour<,>));
        cfg.AddOpenBehavior(typeof(PerformanceBehaviour<,>));
    });
}
基础设施层服务注册

基础设施层负责数据访问和身份认证等外部依赖的注册:

public static void AddInfrastructureServices(this IHostApplicationBuilder builder)
{
    // 数据库上下文配置
    builder.Services.AddScoped<ISaveChangesInterceptor, AuditableEntityInterceptor>();
    builder.Services.AddScoped<ISaveChangesInterceptor, DispatchDomainEventsInterceptor>();
    
    builder.Services.AddDbContext<ApplicationDbContext>((sp, options) => {
        options.AddInterceptors(sp.GetServices<ISaveChangesInterceptor>());
        options.UseSqlServer(connectionString);
    });
    
    // 接口与实现映射
    builder.Services.AddScoped<IApplicationDbContext>(provider => 
        provider.GetRequiredService<ApplicationDbContext>());
    builder.Services.AddTransient<IIdentityService, IdentityService>();
}
Web层服务注册

Web层负责HTTP相关的服务配置:

public static void AddWebServices(this IHostApplicationBuilder builder)
{
    builder.Services.AddScoped<IUser, CurrentUser>();
    builder.Services.AddHttpContextAccessor();
    builder.Services.AddExceptionHandler<CustomExceptionHandler>();
    builder.Services.AddOpenApiDocument();
}

接口定义与实现映射

项目通过接口抽象实现了真正的依赖倒置,核心接口定义在应用层:

接口实现所在层作用
IApplicationDbContextApplicationDbContext基础设施层数据访问抽象
IIdentityServiceIdentityService基础设施层身份认证服务
IUserCurrentUserWeb层当前用户信息
// 应用层定义的接口
public interface IApplicationDbContext
{
    DbSet<TodoList> TodoLists { get; }
    DbSet<TodoItem> TodoItems { get; }
    Task<int> SaveChangesAsync(CancellationToken cancellationToken);
}

// 基础设施层的实现
public class ApplicationDbContext : DbContext, IApplicationDbContext
{
    public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options) : base(options) { }
    
    public DbSet<TodoList> TodoLists => Set<TodoList>();
    public DbSet<TodoItem> TodoItems => Set<TodoItem>();
}

MediatR驱动的跨层通信

项目采用MediatR库实现CQRS模式,通过命令和查询对象进行跨层通信:

mermaid

命令/查询处理器示例
// 查询定义
[Authorize]
public record GetTodosQuery : IRequest<TodosVm>;

// 查询处理器
public class GetTodosQueryHandler : IRequestHandler<GetTodosQuery, TodosVm>
{
    private readonly IApplicationDbContext _context;
    private readonly IMapper _mapper;

    public GetTodosQueryHandler(IApplicationDbContext context, IMapper mapper)
    {
        _context = context;
        _mapper = mapper;
    }

    public async Task<TodosVm> Handle(GetTodosQuery request, CancellationToken cancellationToken)
    {
        return new TodosVm
        {
            Lists = await _context.TodoLists
                .AsNoTracking()
                .ProjectTo<TodoListDto>(_mapper.ConfigurationProvider)
                .ToListAsync(cancellationToken)
        };
    }
}
Web端点中的MediatR使用
public class TodoLists : EndpointGroupBase
{
    public async Task<Ok<TodosVm>> GetTodoLists(ISender sender)
    {
        var vm = await sender.Send(new GetTodosQuery());
        return TypedResults.Ok(vm);
    }
}

管道行为与横切关注点

MediatR的管道行为机制实现了AOP编程,处理横切关注点:

mermaid

验证行为实现
public class ValidationBehaviour<TRequest, TResponse> : IPipelineBehavior<TRequest, TResponse>
{
    private readonly IEnumerable<IValidator<TRequest>> _validators;

    public async Task<TResponse> Handle(TRequest request, RequestHandlerDelegate<TResponse> next, CancellationToken cancellationToken)
    {
        if (_validators.Any())
        {
            var validationResults = await Task.WhenAll(
                _validators.Select(v => v.ValidateAsync(new ValidationContext<TRequest>(request), cancellationToken)));
            
            var failures = validationResults.SelectMany(r => r.Errors).ToList();
            if (failures.Count != 0)
                throw new ValidationException(failures);
        }
        
        return await next();
    }
}

服务生命周期管理

项目合理使用不同的服务生命周期:

生命周期使用场景示例
Singleton全局单例服务TimeProvider.System
Scoped请求范围服务IApplicationDbContext, IUser
Transient短暂服务IIdentityService

配置管理与环境适配

依赖注入配置支持多环境适配:

// 数据库配置支持多种数据库类型
builder.Services.AddDbContext<ApplicationDbContext>((sp, options) =>
{
#if (UsePostgreSQL)
    options.UseNpgsql(connectionString);
#elif (UseSqlite)
    options.UseSqlite(connectionString);
#else
    options.UseSqlServer(connectionString);
#endif
});

安全性配置

依赖注入也包含了安全相关的配置:

builder.Services.AddAuthorization(options =>
    options.AddPolicy(Policies.CanPurge, policy => policy.RequireRole(Roles.Administrator)));

这种依赖注入和跨层通信机制的设计确保了Clean Architecture各层之间的松耦合,使得应用程序易于测试、维护和扩展。通过接口抽象和MediatR中介者模式,实现了真正的关注点分离和架构边界的严格维护。

总结

通过全面分析Clean Architecture模板的基础设施层与Web层架构设计,我们可以看到一套完整的企业级应用开发解决方案。该架构通过分层设计实现了高度模块化和关注点分离:基础设施层提供稳定的数据持久化和身份认证基础设施,Web层提供简洁高效的API端点实现。关键设计亮点包括EF Core的拦截器机制实现自动化审计跟踪、接口隔离原则确保层间解耦、MediatR管道行为处理横切关注点,以及Minimal API的端点组架构提供良好的扩展性和维护性。这种架构设计不仅保证了系统的可测试性和可维护性,还为未来的功能扩展和技术演进提供了坚实基础,是现代ASP.NET Core应用程序开发的优秀实践范例。

【免费下载链接】CleanArchitecture Jason Taylor开发的Clean Architecture项目模板同样基于.NET Core,遵循干净架构原则。它提供了一种组织代码结构的良好起点,鼓励面向接口编程和关注点分离,适用于需要长期维护和易于扩展的企业级应用程序开发。 【免费下载链接】CleanArchitecture 项目地址: https://gitcode.com/gh_mirrors/cle/CleanArchitecture

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值