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

I am pulling my hair out a bit on this, in fact, I'm trying to implement a common factory repository, which is invoked as follows:

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

The factory repository is as follows:

 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 next line fails

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

The error I get is:

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

Any ideas on what's going wrong here?

EDIT:

The storage implementation 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 this:

 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(); } 
+9
generics reflection c # factory-pattern
source share
4 answers

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

Instead, you want to use this code:

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

This suggests that you may have used the where for the generic type DocumentLibraryRepository<T> and that the PerpetualDocument type does not meet this constraint

0
source share

Maybe my answer can help someone who has the same error. My scenario:

 public class B { public string Name; } public class A { public EventHandler<B> TypedEvent; public void MyMethod(B item) { if (TypedEvent != null) { TypedEvent(null, item); } } } public class T { public void Run() { A item = new A(); item.TypedEvent += new EventHandler<B>(ItemEvent); } private void ItemEvent(object sender, B b) { b.Name = "Loaded"; } } 

Therefore, at runtime, when the Run () method is loaded (not executed), I get an exception:

GenericArguments [0] .... System.EventHandler'1 [TEventArgs] 'Violates the restriction of the type parameter' TEventArgs' .. for the Run () method.

I do not know if this is a .NET error, but in my case I solved this problem by changing the type of the TypedEvent property in class A from the typed EventHandler<B> to EventHandler . My script has become:

 public class B { public string Name; } public class A { public EventHandler TypedEvent; public void MyMethod(B item) { if (TypedEvent != null) { TypedEvent(item, null); } } } public class T { public void Run() { A item = new A(); item.TypedEvent += new EventHandler(ItemEvent); } private void ItemEvent(object sender, EventArgs e) { B b = sender as B; b.Name = "Loaded"; } } 

I hope this can help someone.

0
source share

I had exactly the same error, but the problem and solution was different. I had 4 model classes, 1 base class, and only 3 of them are inherited from the base, the 4th is not. As soon as the last class inherited the base class, the error disappeared.

0
source share

All Articles