2009-07-14 4 views
0

Normalement, j'aller:Comment ajouter un événement BackgroundWorker RunWorkerCompleted par réflexion?

bgwExportGrid.RunWorkerCompleted += ReportManager.RunWorkerCompleted; 

La classe ReportManager est une classe statique contenant le gestionnaire d'événements que je veux utiliser.

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

Maintenant, j'ai créé un BackgroundWorker et que vous souhaitez joindre l'événement RunWorkerCompleted tel que défini dans ReportManager. Cependant, ReportManager ne peut pas être référencé car sinon une référence cyclique se produit donc une réflexion est nécessaire.

Toute aide serait grandement appréciée.

Je l'ai regardé ce qui suit, mais ne l'ai pas obtenu très loin:

 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

Vous devriez vraiment pas vous peindre dans ce coin ... tirer une interface dans un ensemble commun –

Répondre

4

Je pense que votre code serait plus facile de maintenir à l'avenir si vous abolirait à la place l'interface du ReportManager dans une interface que les deux assemblées peuvent référencer. Mais, si ce n'est pas une option pour vous, je pense que vous essayez d'atteindre quelque chose comme ceci:

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

Notez comment il n'y a pas de référence « dur » entre Form1 et la classe EventHandlers, de sorte que pourrait être toute autre classe résidant dans une autre assemblée; le gestionnaire d'événements est créé et attaché en fonction du nom du type et du nom de la méthode (qui, naturellement, doit avoir la bonne signature).

0

réponse Mise à jour:

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

Je ne peux pas faire ce qui précède que je ne peux pas faire référence à la classe ReportManager du tout, ce qui est la raison pour laquelle je dois utiliser la réflexion . –

+0

Votre question est plutôt ambiguë, qu'essayez-vous de réaliser? – arul

+0

Normalement, vous devriez aller bgwExportGrid.RunWorkerCompleted + = new RunWorkerCompletedEventHandler (ReportManager.RunWorkerCompleted); Pourtant, dans mon cas, je ne peux même pas référencer ReportManager et j'ai donc besoin d'utiliser la réflexion - ce que je ne sais pas comment faire dans ce cas. –

0

Géré pour que cela fonctionne. ReportManager est une classe statique, il n'est donc pas nécessaire d'utiliser 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"); 
Questions connexes