Scott Whitlock
Scott Whitlock

Reputation: 13839

Castle Windsor ResolveAll fails with type argument exception

I'm using Castle Windsor for IoC. It's been working great, but all of a sudden every time I try to run my application, it fails during a ResolveAll call:

var resolved = container.ResolveAll<IValidator>();

It throws this exception:

System.ArgumentException occurred
  Message=The number of generic arguments provided doesn't equal the arity of the generic type definition.
Parameter name: instantiation
  Source=mscorlib
  ParamName=instantiation
  StackTrace:
       at System.RuntimeType.MakeGenericType(Type[] instantiation)
       at Castle.MicroKernel.Handlers.DefaultGenericHandler.ResolveCore(CreationContext context, Boolean requiresDecommission, Boolean instanceRequired) in c:\TeamCity\buildAgent\work\1ab5e0b25b145b19\src\Castle.Windsor\MicroKernel\Handlers\DefaultGenericHandler.cs:line 51
  InnerException: 

The really odd thing is that it's been working great up until today. If I roll back to a version before it started doing this, even back to last week, I still get this error. I've tried rebooting, etc. Has anyone seen this before?

EDIT:

Here's how I'm registering the IValidator ones:

    private void registerFromAssembly(IWindsorContainer container, Assembly assembly)
    {
        container.Register(
            AllTypes.FromAssembly(assembly)
                .BasedOn<IValidator>()
        );
    }

Here's how I'm registering the IPresenterResolver service:

        container.Register(
            Component.For<IPresenterResolver>()
                .ImplementedBy<CommandLineArgumentPresenterResolver>()
        );

I have to remove both of these to get the application to run now.

Upvotes: 0

Views: 1225

Answers (1)

Scott Whitlock
Scott Whitlock

Reputation: 13839

I had to download the Castle Windsor source code so I could debug it at the source of the failure. It turns out that I was incorrectly including some generic base type services where I was only expecting non-generic concrete implementations. I had to change my registration code to this to make it work:

    private void registerFromAssembly(IWindsorContainer container, 
        Assembly assembly)
    {
        container.Register(
            AllTypes.FromAssembly(assembly)
                .BasedOn<IValidator>()
                    .Unless(type => type == typeof(FluentValidatorWrapper<>))
                    .Unless(type => type == typeof(PassEverythingValidator<>))
        );
    }

In this case FluentValidatorWrapper is a generic base type I use to build type-specific validators and PassEverythingValidator is a generic type that my validation logic manually instantiates when it can't find a type-specific validator. These shouldn't have been included in the container.

I made a note on the Castle Windsor mailing list that if the concrete type information had been included in the exception, it would have been easier to debug.

Upvotes: 2

Related Questions