学海无涯

导航

CleanArchitecture 项目分析

清洁架构之项目分析

 一、Core (Domain Model) Project 领域模型项目,领域层

  1. 在清洁架构中,中心焦点应该是实体 Entities 和业务规则 business logic。
  2. 在领域驱动设计中,这个项目就是领域模型。
  3. 该项目应包含所有实体、值对象和业务逻辑 Entities, Value Objects, and business logic.
  4. 相关且应一起变更 change 的实体应分组grouped成一个聚合 Aggregate,以实现高内聚。例如:订单和订单明细,即为紧偶合的相关实例。
  5. 实体Entities应利用封装并应尽量减少公共设置器 public setters.
  6. 实体可以利用领域事件 Domain Events 将更改传达给系统的其他部分
  7. 可以为实体定义用于查询它们的规范 Specifications。即: Sql 查询条件,表关联,可重复使用
  8. 对于实例的变更处理,应通过存储库接口Repository interface(访问数据库的仓储模式)访问实体
  9. 只读即时查询可以使用单独 的查询服务Query Services,而不使用领域模型Domain Model

在这里查看示例:
https://github.com/ardalis/CleanArchitecture/tree/main/sample

二、Use Cases Project 用例项目,应用层

  1. 在清洁架构中,用例(或应用程序服务)项目 Use Cases (or Application Services)是包装域模型的相对较薄的层。
  2. 用例Use Cases通常按功能组织。 这些可能是简单的 CRUD 操作或更复杂的活动。
  3. 用例不应直接依赖于基础设施项目 infrastructure,这使得它们在大多数情况下易于进行单元测试。
  4. 用例通常按照 CQRS 分为命令和查询。
  5. 将用例作为单独的项目可以减少 UI 和基础设施项目中的逻辑量。
  6. 对于更简单的项目,可以省略 Use Cases 项目,并将其行为移至 UI 项目中,作为单独的服务或 MediatR 处理程序,或者简单地将逻辑放入 API 端点中。

三、Infrastructure Project  基础设施项目 ,实现层

  1. 在清洁架构中,基础设施问题与核心业务规则解耦,即业务逻辑与具体实现之间应该解耦
  2. 唯一应该包含与 EFCore、文件、电子邮件、Web 服务、Azure/AWS/GCP 等相关的代码的项目是基础设施。即:具体的实现操作功能
  3. 基础设施应依赖于存在抽象(接口)的领域层(以及可选的应用层)
  4. 基础设施类实现领域层(应用层)项目中的接口。
  5. 这些实现在项目启动时使用 DI 注入。 在本例中,使用项目中定义的“Microsoft.Extensions.DependencyInjection”和扩展方法。

 

using Ardalis.GuardClauses;
using Ardalis.SharedKernel;
using CleanProject.Core.Interfaces;
using CleanProject.Core.Services;
using CleanProject.Infrastructure.Data;
using CleanProject.Infrastructure.Data.Queries;
using CleanProject.Infrastructure.Email;
using CleanProject.UseCases.Contributors.List;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;

namespace CleanProject.Infrastructure;
public static class InfrastructureServiceExtensions
{
  public static IServiceCollection AddInfrastructureServices(
    this IServiceCollection services,
    ConfigurationManager config,
    ILogger logger)
  {
    string? connectionString = config.GetConnectionString("DefaultConnection");
    Guard.Against.Null(connectionString);
    services.AddDbContext<AppDbContext>(options =>
     options.UseSqlServer(connectionString));

    services.AddScoped(typeof(IRepository<>), typeof(EfRepository<>));
    services.AddScoped(typeof(IReadRepository<>), typeof(EfRepository<>));
    services.AddScoped<IListContributorsQueryService, ListContributorsQueryService>();
    services.AddScoped<IDeleteContributorService, DeleteContributorService>();

    services.Configure<MailserverConfiguration>(config.GetSection("Mailserver"));

    logger.LogInformation("{Project} services registered", "Infrastructure");

    return services;
  }
}

  

posted on 2024-04-27 05:22  宁静致远.  阅读(13)  评论(0编辑  收藏  举报