C# 如何使用DI通过IValidatableObject接口向实体提供验证器?

C# 如何使用DI通过IValidatableObject接口向实体提供验证器?,c#,.net,validation,dependency-injection,C#,.net,Validation,Dependency Injection,我的业务层具有实现IValidatableObject的对象。我希望这些实体的业务规则位于外部程序集中,然后调用以下类型的验证器: public IEnumerable<ValidationResult> Validate(ValidationContext vc){} 我想我应该在types工厂向Unity打电话,然后从那里注射 但很多时候,实体只是读取而不是修改,即客户实体。它并不总是需要一个验证器,因为它可能只是支持一个用例,而不是被它修改 所以我想我可以: 创建Custom

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

public IEnumerable<ValidationResult> Validate(ValidationContext vc){}
我想我应该在types工厂向Unity打电话,然后从那里注射

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

所以我想我可以:

  • 创建CustomerEdit类,然后仅在这些类上使用构造函数注入器,而不是在CustomerRead类上使用构造函数注入器,但这会导致类爆炸,而我并不希望这个应用程序出现这种情况
  • 拥有单个客户类,并在需要时注入验证器
  • 对于2,如上所述,IValidatableObject接口实现的验证方法似乎是合适的位置。问题是在很多情况下,这个方法是由我自己以外的代码调用的。例如,来自实体框架,对于某些类型,来自MVC,因为它们将用作模型类

    所以现在我不得不重写框架代码中的方法,这样我就可以进行DI。这似乎不对,但老实说,我不知道为什么

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

    public IEnumerable<ValidationResult> Validate(ValidationContext vc)
    {
    
    var customerValidator = (ICustomerValidator)vc.GetService(typeof(ICustomerValidator));
    return customerValidator.Validate();
    
    }
    
    公共IEnumerable验证(ValidationContext vc) { var customerValidator=(icCustomerValidator)vc.GetService(typeof(icCustomerValidator)); 返回customerValidator.Validate(); } 但如果我开始这么做,我不是刚刚进入了ServiceLocator反模式的整个领域,打破了Demeter定律,让测试成为了一个彻头彻尾的痛苦吗


    那么,有没有更干净的方法来解决这个问题,或者仅仅是从我概述的内容中选择我的权衡问题?

    最重要的原则:

    因此,除非您正在创建100000个业务对象,否则不要费心,一直注入您的验证服务


    如果这样做会对性能造成影响,请根据需要将类拆分为读取/编辑模型。

    史蒂文斯对这个问题的评论让我看到了一些与我的问题相关的博客文章

    这些博客文章的要点是,当被注入的依赖项只是“在某些时候被使用”时,构造函数注入被过度使用了,但是通过将依赖项包含在构造函数中,我们使得它“在任何时候都是必需的”

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

    所以它从

    这在这里被反驳

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

    所以,抛开公认的答案不谈,如果我真的想把我的设计重新推向:将验证器注入到域类中,那么我可以注入一个抽象工厂

    与往常一样,当依赖项的生存期可能短于 消费者,解决方案是(通过构造函数!)注入一个抽象 工厂-马克·希曼


    你认为工程设计过度?是的,你可能是对的。我确实考虑过这个问题,但我想我会问,因为有亲吻,然后有无知…有些东西对我来说也很新鲜只要你有清晰的关注点分离和单元测试,重构应该不会很痛苦。我不确定让你的域实体成为依赖注入上下文的一部分是不是一个好主意。相关:
    public IEnumerable<ValidationResult> Validate(ValidationContext vc)
    {
    
    var customerValidator = (ICustomerValidator)vc.GetService(typeof(ICustomerValidator));
    return customerValidator.Validate();
    
    }