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:
Validate
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 appears that you're trying to put tight couples (ClassA
with ValidatorA
, ClassB
with ValidatorB
) as independent types into a common container. This is pointless. If you must rely on tight coupling like this, forget dependency injection in this regard and just hard-reference the types.
This would make more sense if you could implement a common validator for all classes. For instance, make the classes responsible for providing validation rules, and let Validator
just enforce the rules. Or perhaps just include the whole validation inside your classes, which is probably the most sensible scenario here.
MyBaseClass.Validate()
look like inversion of control, but not like a template method.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With