11

也许这很容易,但是在互联网上搜索它已经让我很头疼

这是问题所在:

interface IValidator
{
    void Validate(object obj);
}

public class ValidatorA : IValidator
{
    public void Validate(object obj) { }
}

public class ValidatorB : IValidator
{
    public void Validate(object obj) { }
}


interface IClassA { }
interface IClassB { }

public class MyBaseClass
{
    protected IValidator validator;

    public void Validate()
    {
        validator.Validate(this);
    }
}

public class ClassA : MyBaseClass, IClassA
{
    //problem: validator should ValidatorA
    public ClassA(IValidator validator) { }
}

public class ClassB : MyBaseClass, IClassB
{
    //problem: validator should ValidatorB
    public ClassB(IValidator validator) { }
}

public class OtherClass
{
    public OtherClass(IClassA a, IClassB b) { }
}


//on Main
var oc = container.Resolve<OtherClass>();

任何的想法?

编辑

我注册了ValidatorAand ValidatorBNamed现在问题是 Castle Windsor 如何将这些验证器正确地注入到ClassAand ClassB,有没有办法做到这一点?还是有更好的解决方案?

如果有人认为我的课程设计是错误的,我愿意提供任何建议。到目前为止,我认为它是正确的。是的,验证器具有特定类的特定配置。但它被抽象是有原因的:

  1. Validator 是一个复杂的对象,有时应该连接到数据库,所以出于单元测试的原因,我必须将接口而不是实现传递给构造函数。
  2. 无法为任何验证器使用不同的接口,因为我使用的唯一方法是Validate
  3. 我认为MyBaseClass.Validate()一个常见的模板方法模式不是吗?
4

2 回答 2

12

无需深入了解您选择的架构的细节,只需关注 Windsor 容器配置:

如果您已向给定接口 ( ) 注册了多个命名实现,则可以使用 using 指定在注册使用者类 ( , )IValidator时要使用哪一个:ClassAClassBServiceOverrides

以下容器配置提供了OtherClass带有ClassAa 的实例和带有 aValidatorAClassB实例ValidatorB

var container = new WindsorContainer();

container.Register(Component.For<IClassA>().ImplementedBy<ClassA>()
    .DependsOn(ServiceOverride.ForKey<IValidator>().Eq("ValidatorA")));
container.Register(Component.For<IClassB>().ImplementedBy<ClassB>()
    .DependsOn(ServiceOverride.ForKey<IValidator>().Eq("ValidatorB")));

container.Register(Component.For<IValidator>().ImplementedBy<ValidatorA>()
    .Named("ValidatorA"));
container.Register(Component.For<IValidator>().ImplementedBy<ValidatorB>()
    .Named("ValidatorB"));

container.Register(Component.For<OtherClass>().ImplementedBy<OtherClass>());

var oc = container.Resolve<OtherClass>();
于 2012-07-04T15:10:03.503 回答
2

看来您正试图将紧密的夫妇(ClassAwith ValidatorAClassBwith ValidatorB)作为独立类型放入一个公共容器中。这是没有意义的。如果您必须像这样依赖紧密耦合,请在这方面忘记依赖注入,只需硬引用类型即可。

如果您可以为所有类实现一个通用验证器,这将更有意义。例如,让类负责提供验证规则,然后Validator 只执行这些规则。或者也许只是在你的类中包含整个验证,这可能是这里最明智的场景。

MyBaseClass.Validate()看起来像控制反转,但不像模板方法。

于 2012-07-04T12:04:39.287 回答