温莎城堡 - 如何命名实例构造函数注入地图(Castle Windsor - How to map

2019-06-26 00:31发布

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

这里的问题是:

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>();

任何的想法?

编辑

我注册ValidatorAValidatorBNamed ,现在的问题温莎城堡如何正确地注入这些验证程序的ClassAClassB ,是有办法做到这一点? 或者有没有更好的解决办法?

如果有人认为我的课堂设计是错误的请,我打开的任何建议。 到目前为止,我认为这是正确的。 是的,验证对特定类别的具体配置。 但也有原因,是抽象:

  1. Validator是一个复杂的对象,有时应该连接到数据库,所以我必须通过接口而不是实现来构造单元测试的原因。
  2. 没办法,使用不同的接口,任何验证的,因为我使用的唯一方法是Validate
  3. 我认为MyBaseClass.Validate()公共模板方法模式是不是?

Answer 1:

没有进入只是专注于温莎容器配置您所选择的架构的详细信息:

如果您已经注册多个命名实现给定的接口( IValidator ),你可以指定你想要注册的消费类(当使用哪一个ClassAClassB使用) ServiceOverrides

下面容器配置提供商的OtherClassClassA与实例ValidatorAClassB与实例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>();


Answer 2:

看来,你试图把紧耦合( ClassAValidatorAClassBValidatorB )作为独立的类型转换成一个共同的容器中。 这是毫无意义的。 如果你必须依靠这样的紧耦合,忘了在这方面的依赖注入,只是硬引用类型。

这将使更多的意义,如果你能实现所有类共同验证。 例如,使类负责提供验证规则,并让Validator刚刚执行规则。 或者,也许只是包括你的类里了整个验证,这可能是最明智的场景在这里。

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



文章来源: Castle Windsor - How to map Named instance in constructor injection