Chrisgh
Chrisgh

Reputation: 1016

Register/Resolve partially closed generic descendant using open generic ancestor type with Castle Windsor

With ancestor class:

abstract class MyOpenGenericAncestor<T, TOptions>

and descendant class:

class MyPartiallyClosedDescendant<T> : MyOpenGenericAncestor<T, MyConcreteOptionsType>

I want to be able to resolve MyPartiallyClosedDescendant using MyOpenGenericAncestor, such as:

MyOpenGenericAncestor<T, TOptions> ResolveGeneric<T, TOptions>(TOptions options)
{
    // assume options are used for stuff
    return _container.Resolve<MyOpenGenericAncestor<T, TOptions>();
}

Is there a way to accomplish this? In this code's current implementation, the registration looks like:

var assemblyFilter = new AssemblyFilter("C:\\thePath\", "MyStuff.*.dll");
var myTypes = Classes
    .FromAssemblyInDirectory(assemblyFilter)
    .BasedOn(typeof(MyOpenGenericAncestor<,>))
    .WithServiceBase()
    .LifestyleTransient();

container.Register(myTypes);

With this registration, the MyPartiallyClosedDescendant is registered as a component, but calling ResolveGeneric(myConcreateOptionsInstance) causes a Castle.MicroKernel.ComponentNotFoundException with the message that no component for supporting the service MyOpenGenericAncestor`2[MyConcreateTType, MyConcreateOptionsType] was found. Getting that exception makes sense, but is there a way to register and/or resolve the descendant by requesting the ancestor?

Upvotes: 3

Views: 149

Answers (1)

Jan Muncinsky
Jan Muncinsky

Reputation: 4408

In Castle, there is IGenericImplementationMatchingStrategy for this purpose. Unfortunately I'm not sure how to use it with convention registration, so at least this...

public class MyOpenGenericAncestorMatchingStrategy : IGenericImplementationMatchingStrategy
{
    public Type[] GetGenericArguments(ComponentModel model, CreationContext context)
    {
        return new[] { context.GenericArguments[1] };
    }
}

container.Register(Component.For(typeof(MyOpenGenericAncestor<,>))
.ImplementedBy(typeof(MyPartiallyClosedDescendant<>), new MyOpenGenericAncestorMatchingStrategy()));

Upvotes: 1

Related Questions