He estado tirando de mi cabello por un tiempo en este caso, esencialmente estoy tratando de implementar una fábrica de repositorios genéricos, que se llama de la siguiente manera:Genéricos y Reflexión - GenericArguments [0] viola la restricción del tipo
var resposFactory = new RepositoryFactory<IRepository<Document>>();
la fábrica repositorio tiene el siguiente aspecto:
public class RepositoryFactory<T> : IRepositoryFactory<T>
{
public T GetRepository(Guid listGuid,
IEnumerable<FieldToEntityPropertyMapper> fieldMappings)
{
Assembly callingAssembly = Assembly.GetExecutingAssembly();
Type[] typesInThisAssembly = callingAssembly.GetTypes();
Type genericBase = typeof (T).GetGenericTypeDefinition();
Type tempType = (
from type in typesInThisAssembly
from intface in type.GetInterfaces()
where intface.IsGenericType
where intface.GetGenericTypeDefinition() == genericBase
where type.GetConstructor(Type.EmptyTypes) != null
select type)
.FirstOrDefault();
if (tempType != null)
{
Type newType = tempType.MakeGenericType(typeof(T));
ConstructorInfo[] c = newType.GetConstructors();
return (T)c[0].Invoke(new object[] { listGuid, fieldMappings });
}
}
}
Cuando trato de llamar a la GetRespository funcionan de la siguiente línea de falla
Type newType = tempType.MakeGenericType(typeof(T));
El error que consigo es:
ArgumentException - GenericArguments [0], 'Framework.Repositories.IRepository`1 [Apps.Documents.Entities.PerpetualDocument]', en 'Framework.Repositories.DocumentLibraryRepository`1 [T] 'viola la restricción de tipo' T '.
¿Alguna idea sobre qué está pasando mal aquí?
EDIT:
La implementación del repositorio es el siguiente:
public class DocumentLibraryRepository<T> : IRepository<T>
where T : class, new()
{
public DocumentLibraryRepository(Guid listGuid, IEnumerable<IFieldToEntityPropertyMapper> fieldMappings)
{
...
}
...
}
Y el IRepository parece:
public interface IRepository<T> where T : class
{
void Add(T entity);
void Remove(T entity);
void Update(T entity);
T FindById(int entityId);
IEnumerable<T> Find(string camlQuery);
IEnumerable<T> All();
}
¿Echas en falta una declaración de devolución allí? ¿Pegaste una copia completa de ese método? –
Además, ¿por qué estás buscando la presencia de un constructor sin parámetros cuando claramente intentas invocar un constructor con parámetros? Si tiene un constructor sin parámetros, es muy probable que sea el 0º constructor devuelto por 'GetConstructors', en cuyo caso se producirá un error al llamarlo * con * parámetros. –
Sí lo siento 'return default (T)' debería estar al final. – Bevan