Esto devolverá todos los tipos que hereden una clase base genérica. No todos los tipos que heredan una interfaz genérica.
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;
Esto devolverá todos los tipos, incluidas las interfaces, los resúmenes y los tipos de hormigón que tienen el tipo genérico abierto en su cadena de herencia.
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()))
select x;
}
Este segundo método encontrará ConcreteUserRepo y IUserRepository en este ejemplo:
public interface ConcreteUserRepo : IUserRepository
{}
public interface IUserRepository : IRepository<User>
{}
public interface IRepository<User>
{}
public class User
{}
Sí, pero solo obtendrá el hormigónrepo e irepo cuando esté en el mismo conjunto. Pero esto está absolutamente bien. – Rookian
¡Buena captura! Tendríamos que tener cuidado de cargar todos los ensamblajes dependientes, no solo escanear el que está actualmente cargado. Aquí hay un SO sobre la carga de todos los ensamblajes: http://stackoverflow.com/questions/2384592/c-net-is-herehere-a-way-to-force-all-referenced-assemblies-to-beloaded- into- –
El tipo de (IRepository <>) funciona solo si el tipo genérico tiene un solo parámetro genérico. ¿Alguna idea para los tipos que tienen más de un parámetro de tipo genérico? – dotnetguy