调用从通用接口的方法与另一种通用方法的结果的一个参数(Invoke a method from a

2019-10-19 07:48发布

我试图做结合其继承某个接口,通过自定义实体框架模型构建器触发的事件被执行的所有类的类。

我有的:

1)一种通用接口IOverride其有一个方法配置(EntityTypeConfiguration实体)

2)实现该接口的几个类。

public class ItemOverride : IOverride<Item>
{
    public void Configure(EntityTypeConfiguration<Item> entity)
    {
        // Do something with entity
    }
}

3)一种方法,该方法集限定了接口的所有类并将它们组合成IOverride的这样的列表:

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)我尽量遵循了在事件中调用方法配置...

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[] {});
            }

但是,在运行实际的事件的时候,我得到一个

Additional information: Late bound operations cannot be performed on types or methods for which ContainsGenericParameters is true.

例外的func.Invoke()行。 我清楚地做错事,但我不是100%肯定它是什么。 我想,也许反映是困惑我,当我根据天气的感觉也许我只是做了一件令人难以置信的愚蠢。 反正在正确的方向轻推可能就够了。

Answer 1:

问题是,你是从获得方法IOverride<>而不是从真正的类型。 因此它没有引用继承人。 而且,当你调用func.Invoke你应该通过实例继承的IOverride<>现在要传递EntityTypeConfiguration<T>您在得到invoked变量。 但是,这个变量应该作为参数。

在这里工作的例子。

var entityMethod = typeof(DbModelBuilder).GetMethod("Entity");
var builder = args.ModelBuilder;
foreach (Type x in assembly.GetTypes())
{
    foreach (Type z in x.GetInterfaces())
    {
        Type y = x.BaseType;
        if ((y != null && y.IsGenericType && typeof(IOverride<>).IsAssignableFrom(y.GetGenericTypeDefinition())) || 
            (z.IsGenericType && typeof(IOverride<>).IsAssignableFrom(z.GetGenericTypeDefinition())))
        {
            // first difference - we get Configure method from real object, and not from IOverride
            var method = x.GetMethod("Configure");

            var target = z.GetGenericArguments().Single();
            var invoked = entityMethod.MakeGenericMethod(target).Invoke(builder, new object[] { });
            var func = method.MakeGenericMethod(typeof(string));

            // this one block can go to ModelCreating event as in your example,
            // but locally i didn't use it

            // second difference - we create instance of original type
            var obj = Activator.CreateInstance(x);
            // third one difference - we pass instance as `this` and pass invoked as parameter
            func.Invoke(obj, new[] { invoked });

        }
    }
}


文章来源: Invoke a method from a generic interface with a parameter of a result of another generic method