3

我的业务层有实现 IValidatableObject 的对象。我希望这些实体在外部程序集中的业务规则,然后调用类型的验证器:

public IEnumerable<ValidationResult> Validate(ValidationContext vc){}

我打算使用 DI 将验证器注入到实现 IValidatableObject 接口的类型的构造函数中。

   public Customer(ICustomerValidator validator)
        {
            this.Validator = validator;
        }

我想我会在类型工厂中调用 Unity 并从那里注入。

但是很多时候实体只是读取而不是修改,即客户实体。它并不总是需要一个验证器,因为它可能只是为了支持一个用例而实际上并没有被它修改。

所以我想我可以:

  1. 制作 CustomerEdit 类,然后仅在这些类上使用构造函数注入器,而不是在 CustomerRead 类上使用,但这会导致类爆炸,而我并不真正想要这个应用程序。
  2. 有一个客户类并在需要时注入验证器。

对于如上 2 中 IValidatableObject 接口的实现的 Validate 方法似乎是合适的地方。问题是在许多情况下,这个方法是由我自己的代码以外的代码调用的。例如,来自实体框架和某些类型,来自 MVC,因为它们将用作模型类。

所以现在我不得不重写框架代码中的方法,这样我才能进行 DI。这“似乎”不正确,但老实说,我不知道为什么。

我接下来要看的是 ValidationContext 的 GetService() 方法。

public IEnumerable<ValidationResult> Validate(ValidationContext vc)
{

var customerValidator = (ICustomerValidator)vc.GetService(typeof(ICustomerValidator));
return customerValidator.Validate();

}

但是如果我开始这样做,我不是刚刚踏入了ServiceLocator反模式的整个领域,打破了Demeter法则,让测试变得痛苦吗?

那么有没有更清洁的方法来解决这个问题,还是只是从我概述的内容中选择我的权衡?

4

2 回答 2

2

最重要的原则:KISS

因此,除非您要创建 10000 个业务对象,否则不要打扰,并一直注入您的验证服务。

如果这样做会降低性能,请在需要时将类拆分为读取/编辑模型。

于 2013-03-27T08:34:34.273 回答
1

Stevens 对这个问题的评论让我看到了几篇与我的问题相关的博客文章。

这些博客文章的要点是,当注入的依赖项仅“在某些时候使用”时,构造函数注入被过度使用,但是通过将依赖项包含在构造函数中,我们使其“始终需要”。

在本文的情况下,所描述的依赖项是 OrderShipper,但根据我的问题,它可以很容易地成为验证器。

所以它从

构造函数过度注入反模式 - Jeffrey Palermo

在这里反驳

反驳:Mark Seemann 的构造函数过度注入反模式

然后在这里进一步细化反驳:

Mark Seemann 为惰性组件启用 DI

所以除了接受答案之外,如果我真的想重新设计我的设计:将验证器注入域类,那么我可以注入一个 AbstractFactory。

与往常一样,当依赖项的生命周期可能比消费者短时,解决方案是注入(通过构造函数!)一个抽象工厂 - Mark Seemann

于 2013-03-28T02:45:29.767 回答