Reputation: 474
I have a hierarchy of generic interfaces, where every interface is related to IOperator<T1,T2>
.
interface IOperator<T1, T2>
{
Func<T1, T2, bool> GetFunc()
}
IOperator : IOperator<object, object>
interface IMatchingOperator : IOperator<string, string> { }
interface IComparisonOperator<T1, T2> : IOperator<T1, T2>
where T1: IComparable<T2> { }
interface IComparisonOperator<T> : IComparisonOperator<T, T>
where T: IComparable<T> { }
interface IComparisonOperator : IComparisonOperator<IComparable, object>
I have a lot of classes (not generic) that implement one or more of these interfaces, for example:
class GreaterThanOperator :
IComparisonOperator,
IComparisonOperator<decimal>,
IComparisonOperator<DateTime>,
IComparisonOperator<DateTime, string>
{ ... }
class EqualComparator: IOperator
class RegexOperator : IMatchingOperator { ... }
Now, I want a to create a factory that can load and instantiate every class in the assemblies that in some way implements the parent interface "IOperator", and put it in a collection.
I tried with:
AppDomain.CurrentDomain.GetAssemblies()
.SelectMany(x => x.GetTypes())
.Where(
x => x.IsGenericType
&& x.GetGenericTypeDefinition() == typeof(IOperator<,>)
&& !x.IsInterface && !x.IsAbstract))
.Select(x => Activator.CreateInstance(x)).ToList();
but it doesn't work.
I want the final list to hold one instance of each IOperator
class.
I will then navigate the objects with reflection to see what generic types they use.
Upvotes: 3
Views: 1237
Reputation: 727077
The Where
clause should not check for generic type, because your classes, GreaterThanOperator
etc., are not themselves generic classes. In addition, IOperator<,>
is not a definition of your types: it is a type definition of one of the interfaces implemented by it.
Here is how you could perform the selection:
var res = AppDomain.CurrentDomain.GetAssemblies()
.SelectMany(x => x.GetTypes())
.Where(x =>
!x.IsAbstract
&& !x.IsInterface
&& x.GetInterfaces().Any(i =>
i.IsGenericType()
&& i.GetGenericTypeDefinition() == typeof(IOperator<,>)
)
).Select(x => Activator.CreateInstance(x)).ToList();
Upvotes: 4