Reputation: 9131
I have a method with this signature:
public void GenerateLog<TEntity>(TEntity entity) where TEntity : EntityObject
How can I loop through my ObjectContext and call this for each Entity in my ObjectContext?
I know that I can do this:
foreach (ObjectStateEntry entry in
context.ObjectStateManager.GetObjectStateEntries(
EntityState.Added | EntityState.Modified))
{
string entityName = entry.Entity.GetType().Name;
}
But I don't know how to go from a String representation of the name to GenerateLog<MYSTRING>
instead of GenerateLog<TEntity>
.
Upvotes: 0
Views: 1075
Reputation: 4283
You need to make a generic method from your GenerateLog
and then call that. I normally need to mess around a bit before I get something like this to work, but this should be close
MethodInfo generateLog = typeof(YourClass)
.GetMethod("GenerateLog", BindingFlags.Public | BindingFlags.Instance );
MethodInfo genericGenerateLog = generateLog.MakeGenericMethod(entry.Entity.GetType());
genericGenerateLog.Invoke(this, new object[] { entry.Entity });
YourClass
is simply the class the GenerateLog is in.
Upvotes: 2
Reputation: 7135
As Drew Marsh said, there's no way to call a generic method with only the name of the generic Type argument. Because of that, I can only suggest what you may well judge to be a bit of a rubbish solution using runtime method resolution - although it would work...
Firstly, assign a dynamic variable inside the foreach
, and call a private method named (e.g.) CallGenerateLog()
:
foreach (ObjectStateEntry entry in
context.ObjectStateManager.GetObjectStateEntries(
EntityState.Added | EntityState.Modified))
{
dynamic dynamicEntity = entry.Entity;
CallGenerateLog(dynamicEntity);
}
...provide one overload of CallGenerateLog()
for each of the Entity types you want to log, and have each one call your GenerateLog()
method, e.g.:
private static void CallGenerateLog(User user)
{
GenerateLog(user);
}
private static void CallGenerateLog(Customer customer)
{
GenerateLog(customer);
}
...etc... and provide a catch-all overload which will satisfy the compiler and be called if an Entity type you don't have an explicit overload for is found.
private static void CallGenerateLog(object entity)
{
}
Problems with this include:
You need an overload of CallGenerateLog()
for each Entity type, so if you add a new Entity type which you want to log you'll have to remember to add an overload for it (although you could address this with T4 templates)
There is some overhead to runtime method resolution, so you may have to profile how well the method performs and decide if it's going to cause you any problems.
Upvotes: -1