1

I have a function which make repository Dictionary, of multiple tables at run time, What i want is make this as generic, but I am stuck on this error..

 public IRepository<TEntity> GetRepository<TEntity>(string TypeName) where TEntity : class { Type t = GetInstance(TypeName); if (_repositories.Keys.Contains(t)) { return _repositories[t] as IRepository<TEntity>; } var repository = new Repository<TEntity>(_context); _repositories.Add(t, repository); return repository; } 

When I call this function as

 string tn = tt.GetType().FullName; Type tttt = GetInstance(tn); uu.GetRepository<Object>(tn).Add(tt); 

it throws Exception

The entity type Object is not part of the model for the current context.

how can I make this happen as

string tn = tt.GetType().FullName; Type tttt = GetInstance(tn); uu.GetRepository<typeof(tt)>(tn).Add(tt); 

or something type else.

7
  • You can make it via reflection, but what's the point? It will then ignore all benefits of generic type parameters. Why do you want to do this? Commented May 11, 2016 at 8:07
  • Do you initialize function "uu" ? Commented May 11, 2016 at 8:08
  • you are using Entity Framework? Commented May 11, 2016 at 8:11
  • @Evk i have a scenerio through which every time I wanted to save and update, delete all records dynamically which were created dynamically. Commented May 11, 2016 at 8:11
  • @LinhTuan, yeah I initialize uu Commented May 11, 2016 at 8:12

2 Answers 2

1

If you just want to know how to do it in principle (if ignore questions about should you do that at all or not), then here is how:

 string tn = tt.GetType().FullName; // get reference to GetRepository<TEntity> var genericGet = uu.GetType().GetMethod("GetRepository").MakeGenericMethod(tt.GetType()); // invoke to get IRepository<TEntity> var repository = genericGet.Invoke(uu, new object[] { tn}); // get IRepository<TEntity>.Add var addMethod = repository.GetType().GetMethod("Add"); // invoke addMethod.Invoke(repository, new object[] { tt}); 

If you would go this way - better make your Add methods accept object instead of generic type argument, and so make your interface just IRepository, not IRepository<T>. Then inside repository - get reference to specific DbSet and Add method using technique above.

Sign up to request clarification or add additional context in comments.

2 Comments

Yeah, It's Work, but If there any solution other than this?
@user6002727 as I remember, Entity Framework context has untyped DbSets. Something like context.Set(typeof(YourEntity)). You can just use those sets then (again, your IRepository would be without generic parameters).
1

If you want it to be generic, you need to specify a type as a generic parameter. The client code must know the type, not just have an instance of that type.

In your case, using Object as a generic type argument does not make sense, because that would not provide the type inference for the underlying framework. That is the reason for the exception thrown.

Also, at runtime, if your solution is multithreaded, you can't use Dictionary without extra synchronization. For your task, I'd recommend ConcurrentDictionary.

void Main() { var repository = GetRepository<MyEntity1>(); MyEntity1 instance = repository.Get(1); } class MyEntity1 { } ConcurrentDictionary<Type, object> repositories = new ConcurrentDictionary<System.Type, object>(); interface IRepository<T> { T Get(int id); } class Repository<T> : IRepository<T> where T:new() { public T Get(int id) { return new T(); } } IRepository<T> GetRepository<T>() where T:new() { return (IRepository<T>)repositories.GetOrAdd(typeof(T), t => new Repository<T>()); } 

1 Comment

Nice Idea of ConcurrentDictionary.. like that

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.