Reputation: 21328
For the following container registration:
c.For(typeof(IHandler<bool>)).Use(typeof(BoolHandler));
c.For(typeof(IHandler<int>)).Use(typeof(IntHandler));
I'm trying to get a list of types at run time like so:
var test = Container.Current.Get(typeof(IHandler<>)); // doesn't work
var test = Container.Current.GetAllInstances<IHandler<object>>(); // doesn't work
I get count of 0;
Upvotes: 1
Views: 702
Reputation: 172646
You can't call Get(typeof(IHandler<>))
because it is impossible to create an instance of an open-generic type; this is impossible in the CLR.
Resolving a collection of IHandler<object>
would only result any elements either when you have explicitly registered an IHandler<object>
-or- when the IHandler<T>
is defined as covariant, i.e. using the out
keyword as IHandler<out T>
. Without having in
or out
keywords on your interface, your interface is not variant and it is impossible to cast a closed version of an interface to another closed version of that same interface.
Only when the abstraction is defined as IHandler<out T>
is is possible to assign an IHandler<string>
to an IHandler<object>
because T
will be an output argument and string
can be casted to object
.
It is unlikely that this is useful to you, since handlers typically have an input argument. However, when the abstraction is defined as IHandler<in T>
(which makes much more sense) this means that you can only assign an IHandler<object>
from an IHandler<string>
, because you can pass in a string argument into an IHandler<object>
but not the other way around.
To make this more concrete, the following will compile:
interface IHandler<in T> { }
var handlers = new IHandler<string>[]
{
new Handler<string>(),
new Handler<object>(),
};
But the following won't:
interface IHandler<in T> { }
var handlers = new IHandler<object>[]
{
new Handler<string>(),
new Handler<object>(),
};
Likewise, the following will compile:
interface IHandler<out T> { }
var handlers = new IHandler<object>[]
{
new Handler<string>(),
new Handler<object>(),
};
But the following won't:
interface IHandler<out T> { }
var handlers = new IHandler<string>[]
{
new Handler<string>(),
new Handler<object>(),
};
Since this holds for C# and the CLR in general, there is no way for StructureMap (or any container) to work around this. And that's why you won't got any results.
Upvotes: 1