对于以下容器注册:
c.For(typeof(IHandler<bool>)).Use(typeof(BoolHandler));
c.For(typeof(IHandler<int>)).Use(typeof(IntHandler));
我试图在运行时获取类型列表,如下所示:
var test = Container.Current.Get(typeof(IHandler<>)); // doesn't work
var test = Container.Current.GetAllInstances<IHandler<object>>(); // doesn't work
我得到0;
答案 0 :(得分:1)
您无法调用Get(typeof(IHandler<>))
,因为无法创建开放泛型类型的实例;这在CLR中是不可能的。
当IHandler<object>
定义为协变时,即使用{{1>时,解析IHandler<object>
的集合只会导致任何元素显式注册IHandler<T>
- 或 - 关键字为out
。如果您的界面没有IHandler<out T>
或in
个关键字,那么您的界面不是变体,并且无法将接口的封闭版本转换为同一界面的另一个封闭版本。
只有在将抽象定义为out
时才可以将IHandler<out T>
分配给IHandler<string>
,因为IHandler<object>
将是输出参数,T
可以投放到string
。
这不太可能对您有用,因为处理程序通常具有输入参数。但是,当抽象定义为object
时(这更有意义),这意味着您只能从IHandler<in T>
分配IHandler<object>
,因为您可以将字符串参数传入IHandler<string>
而不是相反。
为了使其更具体,以下将编译:
IHandler<object>
但以下情况不会:
interface IHandler<in T> { }
var handlers = new IHandler<string>[]
{
new Handler<string>(),
new Handler<object>(),
};
同样,以下内容将编译:
interface IHandler<in T> { }
var handlers = new IHandler<object>[]
{
new Handler<string>(),
new Handler<object>(),
};
但以下情况不会:
interface IHandler<out T> { }
var handlers = new IHandler<object>[]
{
new Handler<string>(),
new Handler<object>(),
};
由于这通常适用于C#和CLR,因此StructureMap(或任何容器)无法解决此问题。这就是为什么你不会得到任何结果。