使用C#的干净体系结构:一种在值对象中执行验证的更好设计

问题描述 投票:2回答:3

我正在创建一个基于Uncle Bob's Clean Architecture概念和DDD的体系结构基于的应用程序。请注意,它是DDD上的BASED,因此我给了自己与严格DDD不同的自由。

要创建此应用程序,我将C#与.Net Standard 2.0一起使用

DDD的原理之一与价值对象有关。根据Wikipedia,值对象的定义如下:

值对象

包含属性但没有概念标识的对象。它们应被视为不可变的。

示例:人们交换名片时,通常不会区分每张唯一的名片;他们只关心卡上打印的信息。在这种情况下,名片是价值对象

现在,如果某些验证不成功,我希望我的值对象不允许创建它们。发生这种情况时,实例化期间将引发异常。我真的想在那儿抛出一个异常,因为架构的核心真的不希望任何无效数据到达这一点。

在进一步讨论这个问题之前,为了给大家更多背景知识,here是我的体系结构(注意:仍不完整:]

My Clean Architecture Proposal

我在此体系结构中遵循的规则是:

  1. 一个层只能知道其最直接的最内层邻居的接口
  2. 一个层无法了解任何最外层
  3. 层之间的所有通信都必须通过接口进行
  4. 每个层必须可独立部署
  5. 每一层必须是可独立开发的

为了更好地理解图中的箭头,我建议阅读那些Stack Exchanges的问题:

Explanation of the UML arrows

https://softwareengineering.stackexchange.com/questions/61376/aggregation-vs-composition

现在,我现在面临的挑战是找到一种使用验证器的好方法。在这一点上,我对我的体系结构不满意。问题如下:

由于我可以在给定的时间实例化成千上万个值对象,因此,我不希望值对象的每个实例都具有一个实例方法来执行验证。我希望验证方法是静态的,因为每个实例的逻辑都是相同的。另外,我希望验证逻辑可用于体系结构的上层,以用于执行验证而无需尝试实例化Value Object,从而导致抛出昂贵的异常。

问题是:C#不允许这样做具有静态方法的多态性,所以我不能做类似的事情:

internal interface IValueObject<T>
{
    T Value { get; }
    static bool IsValid(T value);
}

如何在不依赖静态方法多态性的情况下实现此功能,同时又不浪费内存?

c# .net-core domain-driven-design clean-architecture
3个回答
1
投票

我建议您摆脱IsValid(),并让[Value Objects]自检always valid对象。建议使它们不可变,在这方面显然会有所帮助。您只需在创建过程中检查一次不变式即可。

[编辑]

您可能需要将其视为输入验证的第一阶段,而不是值对象不变式实施。如果有大量不安全的数据要转换成值对象,请首先在外层的验证过程中处理它-您可以进行所需的所有性能优化,在其中实现错误逻辑并协调VO创建。] >


1
投票

可以抽象地思考,这是一件好事,但是在编写一些工作代码后应该概括一下。


1
投票

在干净的体系结构中,所有业务逻辑都进入用例交互器。验证规则是业务逻辑的一部分,因此也应纳入用例交互器。

© www.soinside.com 2019 - 2024. All rights reserved.