使用Castle Windsor的开放式通用祖先类型注册/解析部分关闭的通用后代

时间:2017-08-31 23:20:00

标签: c# generics castle-windsor windsor-facilities

使用祖先类:

abstract class MyOpenGenericAncestor<T, TOptions>

和后代类:

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

我希望能够使用MyOpenGenericAncestor解析MyPartiallyClosedDescendant,例如:

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

有没有办法实现这个目标?在此代码的当前实现中,注册如下:

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

container.Register(myTypes);

通过此注册,MyPartiallyClosedDescendant被注册为组件,但调用ResolveGeneric(myConcreateOptionsInstance)会导致Castle.MicroKernel.ComponentNotFoundException,并显示没有找到支持服务MyOpenGenericAncestor`2 [MyConcreateTType,MyConcreateOptionsType]的组件的消息。获得该异常是有道理的,但有没有办法通过请求祖先来注册和/或解决后代?

1 个答案:

答案 0 :(得分:1)

在Castle中,为此目的有IGenericImplementationMatchingStrategy。不幸的是我不确定如何在常规注册中使用它,所以至少这个......

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()));