Windsor Castle - How to Match a Named Instance in a Designer Injection

it may be easy, but an internet search already gives me a headache

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 is how Castle Windsor can correctly insert this validator into ClassA and ClassB , is there any way to do this? or is there a better solution?

If someone thinks my class design is wrong, I open for any advice. So far I think this is correct. Yes, the validator has a specific configuration for a specific class. but there are reasons why he abstracts:

  • Validator is a complex object that once needs to connect to the database, so I MUST pass the interface instead of implementing it to the constructor to justify unit testing.
  • It is not possible to use a different interface for any of Validator, because the only method I used is Validate
  • I think that MyBaseClass.Validate() generic template template right?
+8
c # castle-windsor
source share
2 answers

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

If you registered several named implementations for this interface ( IValidator ), you can specify which one you want to use when registering custom classes ( ClassA , ClassB ) using ServiceOverrides :

The following container configuration provides OtherClass with an instance of ClassA with an instance of ValidatorA and ClassB with 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>(); 
+9
source share

It looks like you are trying to set hard pairs ( ClassA with ValidatorA , ClassB with ValidatorB ) as independent types in a common container. It's pointless. If you have to rely on a tight connection like this, forget about dependency injection in this regard and just copy the types.

This makes sense if you could implement a common validator for all classes. For example, create classes that are responsible for providing validation rules, and let Validator simply abide by the rules. Or maybe just include all the validation in your classes, which is probably the most sensible scenario here.

MyBaseClass.Validate() looks like an inverse of a control, but not like a template method.

+1
source share

All Articles