Reputation: 14518
I have several classes inheriting from abstract class BrowsingGoal
. Some of these implement an interface called ICanHandleIntent<TPageIntent> where TPageIntent: PageIntent
.
To give a concrete example:
public class Authenticate : BrowsingGoal, ICanHandleIntent<AuthenticationNeededIntent>
{
...
}
Now I would like to scan the CurrentDomain's assemblies for all types implementing the ICanHandleIntent
with the AuthenticationNeededIntent
. This is what I have so far but it doesn't seem to find anything:
protected BrowsingGoal FindNextGoal(PageIntent intent)
{
// Find a goal that implements an ICanHandleIntent<specific PageIntent>
var goalHandler = AppDomain.CurrentDomain
.GetAssemblies()
.SelectMany(assembly => assembly.GetTypes())
.FirstOrDefault(t => t.IsAssignableFrom((typeof (BrowsingGoal))) &&
t.GetInterfaces().Any(x =>
x.IsGenericType &&
x.IsAssignableFrom(typeof (ICanHandleIntent<>)) &&
x.GetGenericTypeDefinition() == intent.GetType()));
if (goalHandler != null)
return Activator.CreateInstance(goalHandler) as BrowsingGoal;
}
Some help would be very appreciated!
Upvotes: 2
Views: 5053
Reputation: 727077
This condition is incorrect:
x.IsAssignableFrom(typeof(ICanHandleIntent<>))
a type implementing an instance of a generic interface is not assignable from the generic interface definition itself, which ICanHandleIntent<>
represents.
What you want instead is
x.GetGenericTypeDefinition() == typeof(ICanHandleIntent<>)
The check for the type parameter is also wrong. It should be
x.GetGenericArguments()[0] == intent.GetType()
because you are looking for the type argument, i.e. the type in triangular brackets following the generic name.
Upvotes: 7