I'm trying to make a class which binds all classes which inherit a certain interface to be executed in an event fired by a custom entity framework model builder.
What I have:
1) A generic interface IOverride which has a method Configure(EntityTypeConfiguration entity)
2) Several classes that implement the interface.
public class ItemOverride : IOverride<Item>
{
public void Configure(EntityTypeConfiguration<Item> entity)
{
// Do something with entity
}
}
3) A method which gathers all classes which define the interface and combines them into a list of IOverride's like this:
var list = (from x in assembly.GetTypes()
from z in x.GetInterfaces()
let y = x.BaseType
where
(y != null && y.IsGenericType &&
typeof (IOverride<>).IsAssignableFrom(y.GetGenericTypeDefinition())) ||
(z.IsGenericType &&
typeof (IOverride<>).IsAssignableFrom(z.GetGenericTypeDefinition()))
select z).ToList();
4) I try to follow that up with invoking the method Configure in an event...
var method = typeof (IOverride<>).GetMethod("Configure")
var entityMethod = typeof (DbModelBuilder).GetMethod("Entity");
foreach (var item in list)
{
var target = item.GetGenericArguments().Single();
var invoked = entityMethod.MakeGenericMethod(target).Invoke(args.ModelBuilder, new object[] {});
var func = method.MakeGenericMethod(item);
ModelCreating += (o, eventArgs) => func.Invoke(invoked, new object[] {});
}
However, when running the actual event, I'm getting a
Additional information: Late bound operations cannot be performed on types or methods for which ContainsGenericParameters is true.
Exception on the func.Invoke() line. I'm clearly doing something wrong, but I'm not 100% sure what it is. I'm thinking maybe Reflection is confusing me when I'm feeling under the weather or maybe I just did something incredibly stupid. Anyway a nudge in the right direction could suffice.
The problem is that you are getting method from
IOverride<>
and not from real type. So it hasn't references to inheritor. And also when you callfunc.Invoke
you should pass instance of inheritor ofIOverride<>
, and now you are passingEntityTypeConfiguration<T>
that you get ininvoked
variable. But this variable should go as parameter.Here is working example.