win7iis添加网站,阿里云服务器 网站模板,长沙做黄叶和网站的公司有哪些,南通旅游网站建设原文链接#xff1a;https://logcorner.com/building-microservices-through-event-driven-architecture-part1-application-specific-business-rules/如今#xff0c;洋葱或六边形等架构为代码的可测试性和维护、与外部框架的独立性提供了重要帮助。在本教程中#xff0c;我… 原文链接https://logcorner.com/building-microservices-through-event-driven-architecture-part1-application-specific-business-rules/如今洋葱或六边形等架构为代码的可测试性和维护、与外部框架的独立性提供了重要帮助。在本教程中我将展示如何使用Clean架构以及诸如领域驱动设计DDD、测试行为驱动开发TDD、CQRS、事件溯源、容器化、Oauth2和Oidc等方法和工具来构建微服务架构。关于Clean架构的更多信息我建议您阅读Robert C. Martin (Uncle Bob)的这篇文章https://blog.cleancoder.com/uncle-bob/2012/08/13/the-clean-architecture.html依赖规则同心圆代表软件的不同区域。一般来说越深入代表你的软件层次越高。外圆是战术实现机制内圆是战略核心策略。使这个架构工作的最重要的规则是依赖规则。这个规则说明了源代码依赖只能指向内部。内圈的任何东西都不可能知道外圈的任何东西。特别是在外圈中声明的部分不能被内圈中的代码提及。包括函数类。变量或任何其他命名的软件实体。同样外圈中使用的数据格式不应该被内圈使用特别是如果这些格式是由外圈中的框架生成的。我们不希望外圈的任何东西影响内圈。命令查询责任分离 (CQRS)CQRS将命令与查询分开。命令是更改应用程序状态并且不返回数据的操作。查询是返回数据但不更改应用程序状态的操作。因此在微服务领域通过使用两个数据库创建应用程序CQRS将是一个非常有用的概念1.一个关系型数据库它针对在命令端写入进行了优化。2.查询端使用NoSQL数据库以便尽可能快地读取数据。由于大多数应用程序读取数据的频率远高于写入数据的频率因此在我们的容器化方法中我们可以在2个pod上部署命令端在10个pod上部署查询端。领域驱动设计CQRS适合领域驱动设计。DDD专注于构建丰富的领域模型来处理复杂的业务逻辑。更改数据会导致更多错误。因此清楚地了解应用程序的哪个部分更改了数据以及应用程序的哪个部分不更改数据将有助于可维护性和调试。事件溯源事件溯源将对象的所有更改存储为事件存储中的一系列事件。https://eventstore.org/我将使用这个概念来构建以下内容领域服务实现领域相关的概念实体、值对象、聚合、领域事件在关系数据库中记录一个命令在事件存储中记录一个事件。全部作为一个单元以进行数据更改生产者从事件存储中获取事件并将其发送到服务总线事件存储是一个只附加表消费者服务总线的订阅者从服务总线获取事件并将其作为预先计算的数据写入NoSQL数据库ReadModel服务查询NOSQL数据库发生的一切都保存在事件存储中 我将建立一个系统帮助演讲者和与会者注册和跟踪事件会议、谈话、聚会等…我的项目结构如下EduSync.Speech.Domain容纳核心领域的最内层。它包含我们的领域对象和业务规则。定义了我们的外部接口。数据库、网络连接、文件系统、用户界面或特殊框架都是不允许的。核心领域不知道自己之外的任何东西。这些依赖项及其实现是使用接口注入我们的核心域的。EduSync.Speech.Application指向核心领域并包含特定于应用程序的业务规则。编排数据流并使用领域模型。不依赖于数据库、UI 或特殊框架。EduSync.Speech.Presentation该层包含Web、UI和展示逻辑。在我们的API上下文中这意味着它通过网络接受http请求形式的输入POST/PUT/PATCH/DELETE并以JSON格式的内容返回其输出。EduSync.Speech.Infrastructure该层包含数据库和网关。在这里我们定义数据访问层、存储库等。它包含在我们的Domain中定义的接口的物理实现。 测试驱动开发实现“语音注册”用例为了使我的测试变为绿色我首先需要实现的是RegisterSpeechUseCase使这个架构工作的最重要的规则是依赖规则。这个规则说源代码依赖只能指向内部。内圈中的任何东西都不可能知道外圈中的任何东西。因此让我们定义IRegisterSpeechUseCase接口及其实现RegisterSpeechUseCase。这些类型属于EduSync.Speech.Application。它将输入对象作为命令。然后是接口 然后RegisterSpeechUseCase如下所示让我们定义IUnitOfWork和ISpeechRepository等依赖项这些接口属于核心域将在基础设施上实现。ISpeechRepository需要一个语音实体所以让我们在核心域上创建它一切都编译成功但我的测试失败了。如您所见测试失败是因为我验证需要调用CreateAsync和Commit方法所以让我们在RegisterSpeechUseCase类上调用SpeechRepository.CreateAsync和IUnitOfWork.Commit然后在我的单元测试的arrange部分创建SpeechRepository.CreateAsync和IUnitOfWork.Commit的mock所有测试都是绿色的了但我的代码覆盖率还不够例如如果我注释掉这个块我的测试将成功但如果command为空我的应用程序将在运行时崩溃 让我们添加一个新的测试来修复它 最后LogCorner.EduSync.Speech.Application的代码覆盖率为100%但是如果我替换了赋值会发生什么var title command.Type;
var urlValue command.Title;
var description command.Url;
var type command.Description;
所有测试都会成功但我的应用程序将处于无效状态因为它将插入标题而不是 url...。我可以在测试断言中使用moqSpeechRepository.Verify修复它但我会保留它并在通过引入值对象实现我的领域时修复它下一步我将实现领域模型。源代码可在此处获得RegisterSpeechUseCasehttps://github.com/logcorner/LogCorner.EduSync/tree/Feature/Task/RegisterSpeechUseCase欢迎关注我的个人公众号”My IO“