Generics & Reflection - GenericArguments[0] violates the constraint of type

18,720

Solution 1

Your code tries to create an instance of DocumentLibraryRepository<IRepository<Document>> instead of DocumentLibraryRepository<Document>.

You want to use this code instead:

var genericArgument = typeof(T).GetGenericArguments().FirstOrDefault();
if (tempType != null && genericArgument != null)
{
    Type newType = tempType.MakeGenericType(genericArgument);

Solution 2

I had this exactly same error, but the problem and solution was different. I had 4 Model classes, 1 base class, and only 3 of them inherited from the base, 4th did not. Once the last class inherited the base class, the error disappeared.

Solution 3

This would suggest that perhaps you've used a where constraint on the generic type DocumentLibraryRepository<T> and that the type PerpetualDocument does not match that constraint

Share:
18,720
Bevan
Author by

Bevan

Updated on June 05, 2022

Comments

  • Bevan
    Bevan almost 2 years

    I've been pulling my hair out for awhile on this one, essentially I'm trying to implement a generic repository factory, which is called as follows:

    var resposFactory = new RepositoryFactory<IRepository<Document>>();
    

    The repository factory looks like the following:

    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 });
            }
        }
    }
    

    When I try to call the GetRespository function the following line fails

    Type newType = tempType.MakeGenericType(typeof(T));
    

    The error I get is :

    ArgumentException - GenericArguments[0], 'Framework.Repositories.IRepository`1[Apps.Documents.Entities.PerpetualDocument]', on 'Framework.Repositories.DocumentLibraryRepository`1[T]' violates the constraint of type 'T'.

    Any ideas on what's going wrong here?

    EDIT:

    The implementation of the repository is as follows:

    public class DocumentLibraryRepository<T> : IRepository<T>
                                                    where T : class, new()
    {
       public DocumentLibraryRepository(Guid listGuid, IEnumerable<IFieldToEntityPropertyMapper> fieldMappings)
       {
            ...
       }
    
       ...
    }
    

    And the IRepository looks like:

    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();
        }