0

通常我会去:

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;
4

3 回答 3

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

Form1注意和类之间没有“硬”引用EventHandlers,因此它可能是驻留在任何其他程序集中的任何其他类;事件处理程序是根据类型名称和方法名称创建和附加的(当然,它必须具有正确的签名)。

于 2009-07-14T12:21:26.763 回答
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);
于 2009-07-14T11:41:35.777 回答
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");
于 2009-07-14T13:13:26.790 回答