2009-07-14 6 views
0

は、通常、私は行くだろう:リフレクションによってBackgroundWorker RunWorkerCompletedイベントを追加する方法はありますか?

bgwExportGrid.RunWorkerCompleted += ReportManager.RunWorkerCompleted; 

ReportManagerクラスは、私が使用するイベントハンドラを含む静的クラスです。

public static class ReportManager 
{ 
     public static void RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) 
     { 
     ... 
     } 
} 

は今、私はBackgroundWorkerのを作成し、ReportManagerで定義されているようRunWorkerCompletedイベントを添付するています。ただし、ReportManagerを参照することはできません。そうしないと循環参照が発生するため、リフレクションが必要になります。

ご協力いただければ幸いです。

私は、次のを見てきましたが、非常に遠くもらっていない:

 Assembly assem = Utils.GetAssembly("WinUI.Reporting.Common.dll"); 
     Type reportManagerType = assem.GetModule("WinUI.Reporting.Common.dll").GetType("WinUI.Reporting.Common.ReportManager"); 
     EventInfo evWorkerCompleted = reportManagerType.GetEvent("RunWorkerCompleted"); 
     Type tDelegate = evWorkerCompleted.EventHandlerType; 
+0

あなたは本当にこのコーナーに自分自身を塗装するべきではありません...私はリフレクションを使用する必要がある理由である、全くReportManagerクラスを参照することができないとして、私は上記の操作を行うことができない一般的なアセンブリ –

答えて

4

あなたの場合ReportManagerのインタフェースを、両方のアセンブリが参照できるインタフェースに置き換えることになります。しかし、それはあなたのためのオプションではない場合、私はあなたがこのような何かを達成しようとしていることを考える:

namespace WindowsFormsApplication1 
{ 
    public partial class Form1 : Form 
    { 
     public Form1() 
     { 
      InitializeComponent(); 
      AttachEventHandler(backgroundWorker1, 
        Type.GetType("WindowsFormsApplication1.EventHandlers"), 
        "RunWorkerCompleted"); 
      backgroundWorker1.RunWorkerAsync(); 
     } 

     private void AttachEventHandler(BackgroundWorker bgw, Type targetType, 
      string eventHandlerMethodName) 
     { 
      object targetInstance = Activator.CreateInstance(targetType); 
      bgw.RunWorkerCompleted += 
       (RunWorkerCompletedEventHandler)Delegate.CreateDelegate(
        typeof(RunWorkerCompletedEventHandler), 
        targetInstance, eventHandlerMethodName); 
     } 

    } 

    public class EventHandlers 
    { 
     public void RunWorkerCompleted(object sender, 
      System.ComponentModel.RunWorkerCompletedEventArgs e) 
     { 
      // do something 
     } 
    } 
} 

注意がForm1EventHandlersクラスの間には「ハード」の参照はありませんので、それは可能性がどのように他のどのクラスにも属しているクラス。イベントハンドラは、型の名前とメソッドの名前に基づいて作成され、添付されます(当然、正しい署名が必要です)。

0

更新答:私はあなたのコードは、将来的に維持することが容易になるだろうと思います

Assembly assem = Utils.GetAssembly("WinUI.Reporting.Common.dll"); 

Type reportManagerType = assem.GetModule("WinUI.Reporting.Common.dll").GetType("WinUI.Reporting.Common.ReportManager"); 

// obtain the method info 
MethodInfo mi = reportManagerType.GetMethod("RunWorkerCompleted", 
              BindingFlags.Static | BindingFlags.Public); 

// create a delegate that we can further register with the event 
Delegate handler = Delegate.CreateDelegate(reportManagerType , mi); 

// get the event info from the export grid object 
EventInfo evWorkerCompleted = bgwExportGrid.GetType().GetEvent("RunWorkerCompleted"); 

// invoke the event 
evWorkerCompleted.AddEventHandler(bgwExportGrid, handler); 
+0

へのインタフェースを引きます。 –

+0

あなたの質問はむしろあいまいです。何を達成しようとしていますか? – arul

+0

通常は行くでしょう bgwExportGrid.RunWorkerCompleted + =新しいRunWorkerCompletedEventHandler(ReportManager.RunWorkerCompleted); 私のケースでは、ReportManagerを参照することさえできないため、リフレクションを使用する必要があります。この場合、どのようにすればよいか分かりません。 –

0

ReportManagerは静的なクラスなので、Activator.CreateInstanceを使用する必要はありません。

 Assembly assem = Utils.GetAssembly("WinUI.Reporting.Common.dll"); 
     Type reportManagerType = assem.GetModule("WinUI.Reporting.Common.dll").GetType("WinUI.Reporting.Common.ReportManager"); 
     bgwExportGrid.RunWorkerCompleted += (RunWorkerCompletedEventHandler)Delegate.CreateDelegate(typeof(RunWorkerCompletedEventHandler), reportManagerType, "RunWorkerCompleted");