2012-09-17 34 views
7

tengo algunas clases de esta manera:casting genérico para Tipo de interfaz - No se puede convertir objeto de tipo 'System.RuntimeType' para escribir

public class Customer 
{ } 

public interface IRepository 
{ } 

public class Repository<T> : IRepository 
{ } 

public class CustomerRepository<Customer> 
{ } 

Entonces, según the answer to this question puedo utilizar la reflexión para obtener una lista de tipos referenciados por los genéricos para cada uno de mi * Repositorio:

Lo que quiero es terminar con un Dictionary<Type, IRepository>

hasta ahora, tengo esto:

Dictionary<Type, IRepository> myRepositories = Assembly.GetAssembly(typeof(Repository<>)) 
.GetTypes() 
.Where(typeof(IImporter).IsAssignableFrom) 
.Where(x => x.BaseType != null && x.BaseType.GetGenericArguments().FirstOrDefault() != null) 
.Select(
    x => 
    new { Key = x.BaseType != null ? x.BaseType.GetGenericArguments().FirstOrDefault() : null, Type = (IRepository)x }) 
.ToDictionary(x => x.Key, x => x.Type); 

Sin embargo, no le gusta mi yeso (IRepository)x
me sale el siguiente error:

Unable to cast object of type 'System.RuntimeType' to type 'My.Namespace.IRepository'.

+2

¿Cómo espera * que obtenga una instancia cuando solo tiene un 'Tipo'? –

Respuesta

8

no se puede convertir (IRepository) type con el tipo es Type clase,

puede utilizar Activator.CreateInstance para crear objetos CustomerRepository, tampoco necesita utilizar Select, en su lugar, use ToDictionary directamente, el código a continuación:

var myRepositories = Assembly.GetAssembly(typeof(Repository<>)) 
     .GetTypes() 
     .Where(x => x.BaseType != null && 
        x.BaseType.GetGenericArguments().FirstOrDefault() != null) 

     .ToDictionary(x => x.BaseType.GetGenericArguments().FirstOrDefault(), 
          x => Activator.CreateInstance(x) as IRepository); 
2

Si x es un objeto System.Type, como si x es typeof(Repository<>), no puede simplemente lanzarlo así. El Type no es una creación de instancias.

Si x no tenían parámetros de tipo "libre", es decir, si x donde no genérico o cerrado genérico, entonces podría (IRepository)Activator.CreateInstance(x) que crear un objeto de tipo x. Pero no estoy seguro de eso es lo que necesitas. ¿Habrá un constructor de instancias sin parámetros?

Cuestiones relacionadas