2014-02-11 66 views
1

我想做一個類,它將繼承所有繼承特定接口的類,以便在由自定義實體框架模型觸發的事件中執行建設者。從通用接口調用另一種通用方法的結果的參數

我有什麼:

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%確定它是什麼。我想,當我感覺天氣不好時,或許我做了一件非常愚蠢的事情,反思會使我感到困惑。無論如何,在正確的方向微調就足夠了。

回答

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 }); 

     } 
    } 
} 
+0

你的回答使我真正的解決方案。然而,func()是不相關的,只需要調用method.Invoke(obj,new [] {invoked}); – NeroS

相關問題