Как добавить событие BackgroundWorker RunWorkerCompleted через отражение? - PullRequest
0 голосов
/ 14 июля 2009

Обычно я бы пошел:

bgwExportGrid.RunWorkerCompleted += ReportManager.RunWorkerCompleted;

Класс ReportManager - это статический класс, содержащий обработчик событий, который я хочу использовать.

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

Теперь я создал BackgroundWorker и хочу прикрепить событие RunWorkerCompleted, как определено в ReportManager. Однако на 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;

Ответы [ 3 ]

4 голосов
/ 14 июля 2009

Я думаю, что ваш код будет проще поддерживать в будущем, если вы вместо этого извлечете интерфейс из 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 
        }
    }
}

Обратите внимание, что между Form1 и EventHandlers классом нет «жесткой» ссылки, так что это может быть любой другой класс, находящийся в любой другой сборке; обработчик событий создается и присоединяется на основе имени типа и имени метода (который, естественно, должен иметь правильную подпись).

0 голосов
/ 14 июля 2009

удалось заставить его работать. 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");
0 голосов
/ 14 июля 2009

Обновленный ответ:

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