温莎城堡 - 如何命名实例在构造函数注入地图 [英] Castle Windsor - How to map Named instance in constructor injection

查看:139
本文介绍了温莎城堡 - 如何命名实例在构造函数注入地图的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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



现在的问题是:



 接口IValidator 
{
void验证(obj对象);
}

公共类ValidatorA:IValidator
{
公共无效验证(obj对象){}
}

公类ValidatorB:IValidator
{
公共无效验证(obj对象){}
}


接口IClassA {}
接口IClassB { }

公共类MyBaseClass
{
保护IValidator验证;

公共无效的validate()
{
validator.Validate(本);
}
}

公共类ClassA的:MyBaseClass,IClassA
{
//问题:确认者应ValidatorA
公共ClassA的(IValidator验证){}
}

公共类ClassB的:MyBaseClass,IClassB
{
//问题:确认者应ValidatorB
公共ClassB的(IValidator验证){ }
}

公共类OtherClass
{
公共OtherClass(ICla​​ssA一,IClassB b){}
}


//上主要
变种OC = container.Resolve< OtherClass>();



你知道吗?



修改



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



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




  1. Validator是一个复杂的对象,有时需要连接到数据库,所以我必须通过接口而不是实现以构造单元测试的原因。

  2. 没有办法用任何验证程序的不同的接口,因为我使用的唯一方法是验证

  3. 我觉得 MyBaseClass.Validate()一个共同的模板法模式是不是?


解决方案

没有进入您所选择的结构的细节只是专注于温莎容器配置:



如果您已经注册了多个命名执行给定的接口( IValidator ),你可以指定你想要哪一个使用注册用户类( ClassA的 ClassB的)时使用 ServiceOverrides



下面的容器配置提供一个 OtherClass ClassA的实例与 ValidatorA ClassB的实例与 ValidatorB

  VAR集装箱=​​新WindsorContainer(); 

container.Register(Component.For&所述; IClassA>()ImplementedBy&所述。ClassA的>()
.DependsOn(ServiceOverride.ForKey&所述; IValidator方式>()方程(ValidatorA)) );
container.Register(Component.For< IClassB>()ImplementedBy< ClassB的>()
.DependsOn(ServiceOverride.ForKey< IValidator>()式(ValidatorB)));

container.Register(Component.For< IValidator>()ImplementedBy< ValidatorA>()
.Named(ValidatorA));
container.Register(Component.For< IValidator>()ImplementedBy< ValidatorB&G​​T;()
.Named(ValidatorB));

container.Register(Component.For&所述; OtherClass>()ImplementedBy&所述。OtherClass>());

变种OC = container.Resolve< OtherClass>();


maybe this is easy, but searching it on the internet already give me a head ache

here is the problem:

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

Any idea?

EDIT

I registered ValidatorA and ValidatorB with Named, now the problem how Castle Windsor can inject those validator properly to the ClassA and ClassB, is there a way to do that? or is there any better solution?

if there is someone think my class design is wrong please, i open for any advice. So far i think it correct. Yes, validator have specific configuration for specific Class. but there are reasons it is abstracted:

  1. Validator is a complex object, sometime should connect to database, so I MUST pass interface instead of implementation to constructor for unit testing reason.
  2. No way to use different interface for any of Validator, because the only method that i used is Validate
  3. I think MyBaseClass.Validate() a common template method pattern isn't it?

解决方案

Without going into the details of your chosen architecture just focusing on the Windsor container configuration:

If you have registered multiple named implementation to a given interface (IValidator), you can specify which one do you want to use when registering the consumer classes (ClassA, ClassB) with using ServiceOverrides:

The following container configuration providers an OtherClass with ClassA instance with a ValidatorA and ClassB instance with a 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>();

这篇关于温莎城堡 - 如何命名实例在构造函数注入地图的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆