Ardalis.CleanArchitecture.Template 清洁架构模板
dotnet new --install Ardalis.CleanArchitecture.Template::6.2.8
参考:https://www.nuget.org/packages/ardalis.cleanarchitecture.template
设计决策和依赖关系
此示例的目标是为新项目提供一个相当简单的入门工具包。它不包括特定企业应用程序可能从中受益的所有可能的框架、工具或功能。它对数据访问等技术的选择植根于大多数使用微软技术堆栈的商业软件开发人员最常见、最容易获得的技术。它(目前)不包括对日志记录、监控或分析等内容的广泛支持,尽管这些都可以轻松添加。下面是它包含的技术依赖项的列表,以及选择它们的原因。其中大部分可以很容易地替换为您选择的技术,因为这种架构的本质是支持模块化和封装。
Core Project 核心项目
Core 项目是 Clean Architecture 设计的中心,所有其他项目依赖项都应该指向它。因此,它几乎没有外部依赖性。这种情况下的一个例外是System.Reflection.TypeExtensions
包,它被用来ValueObject
帮助实现它的IEquatable<>
接口。核心项目应包括以下内容:
- Entities 实体
- Aggregates 聚合
- Domain Events 领域事件
- DTO
- Interfaces 接口
- Event Handlers 事件处理器
- Domain Services 领域服务
- Specifications 规格
SharedKernel Project 共享内核项目
许多解决方案还将引用一个单独的共享内核项目/包。如果您需要在多个限界上下文之间共享代码,我建议创建一个单独的 SharedKernel 项目和解决方案(请参阅DDD 基础知识)。我进一步建议将其发布为 NuGet 包(很可能在您的组织内私下发布),并由需要它的项目引用为 NuGet 依赖项。对于此示例,为了简单起见,我向解决方案添加了一个 SharedKernel 项目。根据我的经验,它包含可能会在多个限界上下文(通常是 VS 解决方案)之间共享的类型。如果你想看一个SharedKernel 包的示例,我在更新的 Pluralsight DDD 课程中使用的包位于此处的 NuGet 上。
Infrastructure Project 基础设施项目
您的应用程序对外部资源的大部分依赖性应该在基础结构项目中定义的类中实现。这些类应该实现 Core 中定义的接口。如果你有一个非常大的项目,有很多依赖项,那么拥有多个基础设施项目(例如 Infrastructure.Data)可能是有意义的,但对于大多数项目来说,一个带文件夹的基础设施项目就可以正常工作。该示例包括数据访问和域事件实现,但您还可以向该项目添加电子邮件提供商、文件访问、Web API 客户端等内容,这样它们就不会向您的核心或 UI 项目添加耦合。
基础设施项目依赖于Microsoft.EntityFrameworkCore.SqlServer
和Autofac
。使用前者是因为它内置于默认的 ASP.NET Core 模板中,并且是数据访问的最小公分母。如果需要,它可以很容易地替换为像 Dapper 这样的轻量级 ORM。Autofac(以前称为 StructureMap)用于允许依赖关系的连接发生在离实现所在位置最近的地方。在这种情况下,可以在 Infrastructure 类中使用 InfrastructureRegistry 类以允许在那里连接依赖项,而应用程序的入口点甚至不必引用项目或其类型。了解有关此技术的更多信息。当前的实施不包括这种行为——这是我通常涵盖的内容,并让学生在我的研讨会中加入他们自己。
Web Project 网络项目
应用程序的入口点是 ASP.NET Core Web 项目。这实际上是一个控制台应用程序,public static void Main
在Program.cs
. 它目前使用默认的 MVC 组织(Controllers 和 Views 文件夹)以及大多数默认的 ASP.NET Core 项目模板代码。这包括它的配置系统,它使用默认appsettings.json
文件加上环境变量,并在Startup.cs
. 项目委托Infrastructure
项目使用 Autofac 连接其服务。
Test Projects 测试项目
测试项目可以根据测试的类型(单元、功能、集成、性能等)或他们正在测试的项目(核心、基础设施、Web)或两者来组织。对于这个简单的入门工具包,测试项目是根据测试的类型组织的,该解决方案中存在单元、功能和集成测试项目。在依赖关系方面,有以下三点值得注意:
-
xunit我使用 xunit 是因为 ASP.NET Core 在内部使用它来测试产品。它工作得很好,随着 ASP.NET Core 新版本的发布,我相信它会继续很好地工作。
-
Moq我正在使用 Moq 作为基于白盒行为的测试的模拟框架。如果我有一个方法,在某些情况下,应该执行对象的可观察状态中不明显的操作,模拟提供了一种测试方法。我也可以使用我自己的 Fake 实现,但这需要更多的输入和文件。一旦你掌握了它,并且假设你不必模拟世界(我们在这种情况下不需要模拟,因为良好的模块化设计),Moq 就很棒。
-
Microsoft.AspNetCore.TestHost我正在使用 TestHost 使用其完整堆栈来测试我的 Web 项目,而不仅仅是单元测试操作方法。使用 TestHost,您无需通过网络即可发出实际的 HttpClient 请求(因此没有防火墙或端口配置问题)。测试在内存中运行并且速度非常快,请求会使用完整的 MVC 堆栈,包括路由、模型绑定、模型验证、过滤器等。
使用的模式
此解决方案模板内置代码以支持一些常见模式,尤其是领域驱动设计模式。以下是其中一些如何工作的简要概述。
Domain Events 领域事件
域事件是一种很好的模式,可以将操作的触发器与其实现分离。这对于域实体内部特别有用,因为事件的处理程序可以具有依赖性,而实体本身通常没有。在示例中,您可以看到该ToDoItem.MarkComplete()
方法的实际效果。以下序列图演示了当通过 Web API 端点将项目标记为完成时如何使用事件及其处理程序。