学海无涯

导航

CleanArchitecture 设计决策和依赖关系

设计决策和依赖关系

Core 核心项目

Core 项目是 Clean Architecture 设计的中心,所有其他项目依赖项都应指向它。因此,它几乎没有外部依赖项。在这种情况下,一个例外是System.Reflection.TypeExtensions包,它用于ValueObject帮助实现其IEquatable<>接口。核心项目应包括以下内容:

  • Entityes 实体
  • Aggregates 聚合
  • Domain Events 领域事件
  • DTOs 传输介质
  • Interfaces 接口
  • Event Handlers 事件处理程序
  • Doamin Services 领域服务
  • Specifications 规则设计

SharedKernel 共享内核项目

许多解决方案还将引用单独的共享内核项目/包。如果您需要在多个有界上下文之间共享代码,我建议创建一个单独的 SharedKernel 项目和解决方案(请参阅DDD 基础知识)。我进一步建议将其作为 NuGet 包发布(很可能在您的组织内私下发布),并被那些需要它的项目作为 NuGet 依赖项引用。对于这个示例,为了简单起见,我在解决方案中添加了一个 SharedKernel 项目。根据我的经验,它包含可能在多个有界上下文(通常是 VS 解决方案)之间共享的类型。如果你想看一个SharedKernel 包的示例,我在更新的 Pluralsight DDD 课程中使用的包在 NuGet 上

Infrastructure 基础设施项目

您的应用程序对外部资源的大部分依赖项应该在基础设施项目中定义的类中实现。这些类应该实现 Core 中定义的接口。如果您有一个具有许多依赖项的非常大的项目,那么拥有多个基础设施项目(例如 Infrastructure.Data)可能是有意义的,但对于大多数项目来说,一个带有文件夹的基础设施项目可以正常工作。该示例包括数据访问和域事件实现,但您还将向此项目添加电子邮件提供程序、文件访问、Web api 客户端等内容,因此它们不会向您的核心或 UI 项目添加耦合。

基础设施项目依赖于Microsoft.EntityFrameworkCore.SqlServerAutofac使用前者是因为它内置在默认的 ASP.NET Core 模板中,并且是数据访问的最小公分母。如果需要,它可以很容易地用像 Dapper 这样的轻量级 ORM 替换。Autofac(以前的 StructureMap)用于允许在最接近实现所在的位置进行依赖关系的连接。在这种情况下,可以在 Infrastructure 类中使用 InfrastructureRegistry 类以允许在那里连接依赖项,而应用程序的入口点甚至不必引用项目或其类型。了解有关此技术的更多信息。当前的实现不包括这种行为——这是我通常会涵盖的内容,并让学生自己添加到我的研讨会中。

Web 项目

应用程序的入口点是 ASP.NET Core Web 项目。这实际上是一个控制台应用程序,public static void MainProgram.cs它目前使用默认的 MVC 组织(Controllers 和 Views 文件夹)以及大多数默认的 ASP.NET Core 项目模板代码。这包括它的配置系统,它使用默认appsettings.json文件加上环境变量,并在Startup.cs该项目委托该Infrastructure项目使用 Autofac 连接其服务。

测试项目

测试项目可以根据测试类型(单元、功能、集成、性能等)或它们正在测试的项目(核心、基础设施、Web)或两者来组织。对于这个简单的入门工具包,测试项目是根据测试类型组织的,单元、功能和集成测试项目存在于这个解决方案中。在依赖方面,有三点值得注意:

  • xunit我使用 xunit 是因为 ASP.NET Core 在内部使用它来测试产品。它运行良好,并且随着新版本的 ASP.NET Core 发布,我相信它将继续与它一起运行良好。

  • Moq我使用 Moq 作为基于行为的白盒测试的模拟框架。如果我有一个方法,在某些情况下,应该执行从对象的可观察状态中不明显的操作,模拟提供了一种测试方法。我也可以使用我自己的 Fake 实现,但这需要更多的输入和文件。一旦你掌握了 Moq 的窍门,并且假设你不必模拟这个世界(因为良好的模块化设计,我们在这种情况下不需要模拟),Moq 就很棒。

  • Microsoft.AspNetCore.TestHost我正在使用 TestHost 来测试我的 web 项目,使用它的完整堆栈,而不仅仅是单元测试操作方法。使用 TestHost,您无需通过网络即可发出实际的 HttpClient 请求(因此没有防火墙或端口配置问题)。测试在内存中运行并且速度非常快,并且请求会执行完整的 MVC 堆栈,包括路由、模型绑定、模型验证、过滤器等。

使用的模式

此解决方案模板具有内置代码以支持一些常见模式,尤其是领域驱动设计模式。以下是其中一些如何工作的简要概述。

领域事件

领域事件是一种很好的模式,可以将操作的触发器与其实现分离。这在域实体中特别有用,因为事件的处理程序可以具有依赖关系,而实体本身通常没有。ToDoItem.MarkComplete()在示例中,您可以通过该方法看到这一点。以下序列图演示了在通过 Web API 端点将项目标记为完成时如何使用事件及其处理程序。

 

posted on 2022-10-23 11:12  宁静致远.  阅读(51)  评论(0编辑  收藏  举报