Ottieni tutti i tipi che implementano un tipo generico aperto specifico

Come ottengo tutti i tipi che implementano uno specifico tipo generico aperto?

Per esempio:

public interface IUserRepository : IRepository 

Trova tutti i tipi che implementano IRepository .

 public static IEnumerable GetAllTypesImplementingOpenGenericType(Type openGenericType, Assembly assembly) { ... } 

Ciò restituirà tutti i tipi che ereditano una class base generica. Non tutti i tipi che ereditano un’interfaccia generica.

 var AllTypesOfIRepository = from x in Assembly.GetAssembly(typeof(AnyTypeInTargetAssembly)).GetTypes() let y = x.BaseType where !x.IsAbstract && !x.IsInterface && y != null && y.IsGenericType && y.GetGenericTypeDefinition() == typeof(IRepository<>) select x; 

Ciò restituirà tutti i tipi, comprese le interfacce, gli abstract e i tipi di calcestruzzo che hanno il tipo generico aperto nella catena di ereditarietà.

 public static IEnumerable 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())) select x; } 

Questo secondo metodo troverà ConcreteUserRepo e IUserRepository in questo esempio:

 public interface ConcreteUserRepo : IUserRepository {} public interface IUserRepository : IRepository {} public interface IRepository {} public class User {} 

Soluzione implementata senza LINQ, cercando interfacce generiche e non generiche, filtrando il tipo restituito in classi.

 public static class SampleCode { public static void Main() { IList loadableTypes; // instance the dummy class used to find the current assembly DummyClass dc = new DummyClass(); loadableTypes = GetClassesImplementingAnInterface(dc.GetType().Assembly, typeof(IMsgXX)).Item2; foreach (var item in loadableTypes) {Console.WriteLine("1: " + item);} // print // 1: Start2.MessageHandlerXY loadableTypes = GetClassesImplementingAnInterface(dc.GetType().Assembly, typeof(IHandleMessageG<>)).Item2; foreach (var item in loadableTypes) { Console.WriteLine("2: " + item); } // print // 2: Start2.MessageHandlerXY // 2: Start2.MessageHandlerZZ } ///Read all classs in an assembly that implement an interface (generic, or not generic) // // some references // return all types implementing an interface // http://stackoverflow.com/questions/26733/getting-all-types-that-implement-an-interface/12602220#12602220 // http://haacked.com/archive/2012/07/23/get-all-types-in-an-assembly.aspx/ // http://stackoverflow.com/questions/7889228/how-to-prevent-reflectiontypeloadexception-when-calling-assembly-gettypes // return all types implementing a generic interface // http://stackoverflow.com/questions/33694960/find-all-types-implementing-a-certain-generic-interface-with-specific-t-type // http://stackoverflow.com/questions/8645430/get-all-types-implementing-specific-open-generic-type // http://stackoverflow.com/questions/1121834/finding-out-if-a-type-implements-a-generic-interface // http://stackoverflow.com/questions/5849210/net-getting-all-implementations-of-a-generic-interface public static Tuple> GetClassesImplementingAnInterface(Assembly assemblyToScan, Type implementedInterface) { if (assemblyToScan == null) return Tuple.Create(false, (IList)null); if (implementedInterface == null || !implementedInterface.IsInterface) return Tuple.Create(false, (IList)null); IEnumerable typesInTheAssembly; try { typesInTheAssembly = assemblyToScan.GetTypes(); } catch (ReflectionTypeLoadException e) { typesInTheAssembly = e.Types.Where(t => t != null); } IList classsImplementingInterface = new List(); // if the interface is a generic interface if (implementedInterface.IsGenericType) { foreach (var typeInTheAssembly in typesInTheAssembly) { if (typeInTheAssembly.IsClass) { var typeInterfaces = typeInTheAssembly.GetInterfaces(); foreach (var typeInterface in typeInterfaces) { if (typeInterface.IsGenericType) { var typeGenericInterface = typeInterface.GetGenericTypeDefinition(); var implementedGenericInterface = implementedInterface.GetGenericTypeDefinition(); if (typeGenericInterface == implementedGenericInterface) { classsImplementingInterface.Add(typeInTheAssembly); } } } } } } else { foreach (var typeInTheAssembly in typesInTheAssembly) { if (typeInTheAssembly.IsClass) { // if the interface is a non-generic interface if (implementedInterface.IsAssignableFrom(typeInTheAssembly)) { classsImplementingInterface.Add(typeInTheAssembly); } } } } return Tuple.Create(true, classsImplementingInterface); } } public class DummyClass { } public interface IHandleMessageG { } public interface IHandleMessage { } public interface IMsgXX { } public interface IMsgXY { } public interface IMsgZZ { } public class MessageHandlerXY : IHandleMessageG, IHandleMessage, IMsgXX { public string Handle(string a) { return "aaa"; } } public class MessageHandlerZZ : IHandleMessageG, IHandleMessage { public string Handle(string a) { return "bbb"; } } 

Potresti provare

 openGenericType.IsAssignableFrom(myType.GetGenericTypeDefinition()) 

o

 myType.GetInterfaces().Any(i => i.Type == openGenericType)