C# How can I dynamically instantiate classes with mixed generic types?

-1

I have this code that correctly discovers all the classes in my assembly implementing the interface I need, but because they are all of generic types, I can't instantiate them. For some of these the type is known and hardcoded but for others, it's user supplied:

        public void DiscoverImples()
        {
            var type = typeof(IOperator<,>);
            var types = AppDomain.CurrentDomain.GetAssemblies().SelectMany(a => GetAllTypesImplementingOpenGenericType(type, a)).Select(Activator.CreateInstance).ToList();
            Console.WriteLine(types);
        }

        public static IEnumerable<Type> GetAllTypesImplementingOpenGenericType(Type openGenericType, Assembly assembly)
        {
            
            return from x in assembly.GetTypes()
                   from z in x.GetInterfaces()
                   let y = x.BaseType
                   where
                       (y != null && y.IsGenericType && openGenericType.IsAssignableFrom(y.GetGenericTypeDefinition())) ||
                       (z.IsGenericType && openGenericType.IsAssignableFrom(z.GetGenericTypeDefinition())) &&
                       (!x.IsAbstract)
                   select x;
        }

The error I receive is:

System.ArgumentException
  HResult=0x80070057
  Message=Cannot create an instance of FlightChangeService.Application.Operators.EqualOperator`1[T] because Type.ContainsGenericParameters is true.
  Source=System.Private.CoreLib
  StackTrace:
   at System.RuntimeType.CreateInstanceCheckThis()
   at System.RuntimeType.CreateInstanceDefaultCtor(Boolean publicOnly, Boolean skipCheckThis, Boolean fillCache, Boolean wrapExceptions)
   at System.Activator.CreateInstance(Type type, Boolean nonPublic, Boolean wrapExceptions)
   at System.Activator.CreateInstance(Type type)
   at System.Linq.Enumerable.SelectEnumerableIterator`2.ToList()
   at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)


In this case, the Operator it's complaining about is

    public interface IOperator<in T, out TResult>
    public abstract class AbstractOperator<T, TOutput> : IOperator<T, TOutput>
    public abstract class LogicalOperator<T> : AbstractOperator<T, bool>
    public sealed class EqualOperator<T> : LogicalOperator<IEquatable<T>>

For what I am trying to do, I have to push off until runtime the type casting. Should I just ditch generics all together and assume everything is an object and type cast in the implementation?

c#

0 Answers

Nobody has answered this question yet.


User contributions licensed under CC BY-SA 3.0