Using Castle Windsor 3.0 to inject dependencies when the classes inherit from the same base class

1,075 views
Skip to first unread message

Steven

unread,
Feb 11, 2012, 7:31:54 AM2/11/12
to Castle Project Development List
I have two classes that inherit from the same base class.

public class UserDetailValidator : BaseValidator<UserDetail>{
public UserDetailValidator(IRepository<Person, Guid> userRepository,
AddressValidator addressValidator)
{
RuleFor(x => x.FirstName).Length(1, 10);
}
}

public class AddressValidator : BaseValidator<Address>

When I try and get the UserDetailValidator from WindsorServiceLocator
I get the error

Missing dependency.
Component UserDetailValidator has a dependency on AddressValidator,
which could not be resolved.
Make sure the dependency is correctly registered in the container as a
service, or provided as inline argument. I'm using the following in
my ValidationInstaller.

container.Register(
AllTypes.FromAssemblyNamed("Validation")
.IncludeNonPublicTypes()
.BasedOn(typeof(IValidator<>))
.WithService.AllInterfaces()
.LifestyleTransient()

The IRepository component is being injected with no problems. It's
only the AddressValidator that does not come in. What am I not doing
properly?

Patrick Steele

unread,
Feb 11, 2012, 9:21:42 AM2/11/12
to castle-pro...@googlegroups.com
What does BaseValidator<T> look like? Does it implement IValidator<T>?

---
Patrick Steele
http://weblogs.asp.net/psteele

> --
> You received this message because you are subscribed to the Google Groups "Castle Project Development List" group.
> To post to this group, send email to castle-pro...@googlegroups.com.
> To unsubscribe from this group, send email to castle-project-d...@googlegroups.com.
> For more options, visit this group at http://groups.google.com/group/castle-project-devel?hl=en.
>

Steven

unread,
Feb 11, 2012, 9:27:32 AM2/11/12
to Castle Project Development List
Yes, BaseValidator<T> does inherit from IValidator<T>

public abstract class BaseValidator<T> : AbstractValidator<T>,
IValidator<T>

where AbstractValidator is a 3rd party lib base class (Jeremy Skinners
FluentValidation).

On Feb 11, 9:21 am, Patrick Steele <patrick.ste...@gmail.com> wrote:
> What does BaseValidator<T> look like?  Does it implement IValidator<T>?
>
> ---
> Patrick Steelehttp://weblogs.asp.net/psteele

Patrick Steele

unread,
Feb 11, 2012, 11:06:51 AM2/11/12
to castle-pro...@googlegroups.com
I think the problem is that you're using
"WithService.AllInterfaces()". This will register AddressValidator
and UserDetailValidator as IValidator<> services. When you try and
resolve UserDetailValidator, the ctor needs an AddressValidator.
There isn't one registered -- there's two IValidator<T>'s registered,
but your ctor wants an AddressValidator.

If you take out the WithService.AllInterfaces(), you should be okay.
But if you want other components to depend on an IValidator<T>, you'll
probably need to configure some service overrides so Windsor knows
which one of your multiple IValidator<T>'s to use.

I think... :)

---
Patrick Steele
http://weblogs.asp.net/psteele

Steven

unread,
Feb 11, 2012, 11:27:46 AM2/11/12
to Castle Project Development List
Ok, now I get

No component for supporting the service IValidator`1[[UserDetail,
Entities, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]] was
found

If I use WithService.DefaultInterface or Base the code passes, but
it's almost like the underlying base class is getting called instead
of the appropriate subclass...

I'm not sure exactly what you mean by "configure some service
overrides".

On Feb 11, 11:06 am, Patrick Steele <patrick.ste...@gmail.com> wrote:
> I think the problem is that you're using
> "WithService.AllInterfaces()".  This will register AddressValidator
> and UserDetailValidator as IValidator<> services.  When you try and
> resolve UserDetailValidator, the ctor needs an AddressValidator.
> There isn't one registered -- there's two IValidator<T>'s registered,
> but your ctor wants an AddressValidator.
>
> If you take out the WithService.AllInterfaces(), you should be okay.
> But if you want other components to depend on an IValidator<T>, you'll
> probably need to configure some service overrides so Windsor knows
> which one of your multiple IValidator<T>'s to use.
>
> I think...  :)
>
> ---

Patrick Steele

unread,
Feb 11, 2012, 11:35:40 AM2/11/12
to castle-pro...@googlegroups.com
See this article I wrote:

http://visualstudiomagazine.com/articles/2011/12/01/windsor-beyond-dependency-injection.aspx

It talks about service overrides. Basically, you can name your IFoo
implementations and then you can pick which IFoo implementation to use
(based on name) when registering a component that needs an IFoo.

---
Patrick Steele
http://weblogs.asp.net/psteele

Steven

unread,
Feb 11, 2012, 12:11:26 PM2/11/12
to Castle Project Development List
Good article.

However, I found an answer that is more along the lines of what I was
really trying to do. I changed the type of the Argument being passed
to UserDetailValidator from AddressValidator to IValidator<Address>.
I still have to use AllInterfaces (at least in my testing so far) but
it now works.

I guess that it has something to do with the fact I WAS asking for a
concrete type, but all I registered was interfaces. Does that sound
right?



On Feb 11, 11:35 am, Patrick Steele <patrick.ste...@gmail.com> wrote:
> See this article I wrote:
>
> http://visualstudiomagazine.com/articles/2011/12/01/windsor-beyond-de...
>
> It talks about service overrides.  Basically, you can name your IFoo
> implementations and then you can pick which IFoo implementation to use
> (based on name) when registering a component that needs an IFoo.
>
> ---

Patrick Steele

unread,
Feb 11, 2012, 12:13:48 PM2/11/12
to castle-pro...@googlegroups.com
Oh, yeah - that makes things much cleaner!

---
Patrick Steele
http://weblogs.asp.net/psteele

Reply all
Reply to author
Forward
0 new messages