C#反射调用其它DLL的委托事件 传值

在插件式开发。我们要调用其它插件或模块的委托事件时、那么我们需要通过反射。

Module 模块
namespace Module2
{
    /// <summary>
    /// MainWindow.xaml 的交互逻辑
    /// </summary>
    [Plugin("MainWindow", "测试反射")]
    public partial class MainWindow 
    {
        public delegate void TestHandler(string msg,string info,string text);
        public event TestHandler TestEvent;

        public MainWindow()
        {
            InitializeComponent();
        }

        protected virtual void ValueInformation(string text, string info, string tb)
        {
            TestHandler handler = TestEvent;
            if (handler != null)
                handler(text,info,tb);
        }

        private void button1_Click(object sender, RoutedEventArgs e)
        {
            if (TestEvent != null)
            {
            }
            ValueInformation("你好!钓鱼岛是中国的!!","打死小日本!!",textBox1.Text);
        }

        public override void UninstallEvent()
        { 
            //添加已经打开的窗口 :在关闭的时候 要删除此项
            ApplicationSharedData.LoadedPlugins.Remove("Module2.MainWindow");
            base.UninstallEvent();
        }
    }
}

 

反射
 1 /// <summary>
 2         /// 模块之间 委托事件 通信
 3         /// </summary>
 4         /// <param name="currentWindow">当前的Window</param>
 5         /// <param name="reflectioneventName">要反射模块中的 委托事件名称</param>
 6         /// <param name="currentEventName">在当前类中要执行的事件名称</param>
 7         /// <param name="filePath">反射文件的路经</param>
 8         /// <param name="plugin">插件</param>
 9         /// <param name="eventParameter">通信的消息</param>
10         public static void ModulEventCommunication(Window currentWindow, string reflectioneventName,
11                                                    string currentEventName, string filePath, Plugin plugin,
12                                                    object[] eventParameter)
13         {
14             if (reflectioneventName == null)
15                 throw new ArgumentNullException("reflectioneventName");
16             if (currentEventName == null)
17                 throw new ArgumentNullException("currentEventName");
18             if (filePath == null)
19                 throw new ArgumentNullException("filePath");
20             if (eventParameter == null)
21                 throw new ArgumentNullException("eventParameter");
22             try
23             {
24                 Assembly assembly = Assembly.LoadFrom(filePath + plugin.NameSpace + "." + plugin.Exends);
25                 Type[] type = assembly.GetTypes();
26                 foreach (Type t in type)
27                 {
28                     //主要是判断该窗口是否实现 IElementsView 如果没有实现 就不需要反射或者不是插件 
29                     if (t.GetInterface("IElementsView") != null && t.Name == plugin.ClassName)
30                     {
31                         //注:在这里要判断是否已经加载:
32                         if (LoadedPlugins.Contains(t.FullName))
33                         {
34                             return;
35                         }
36                         //反射执行的成员和类型搜索
37                         const BindingFlags myBindingFlags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static;
38                         EventInfo eventInfo = t.GetEvent(reflectioneventName, myBindingFlags);
39                         //获取到当前的类
40                         var obj = (IElementsView)assembly.CreateInstance(t.FullName);
41                         if (eventInfo != null)
42                         {
43                             Type tDelegate = eventInfo.EventHandlerType;
44                             MethodInfo methodHandler = currentWindow.GetType().GetMethod(currentEventName,myBindingFlags);
45                             //创建委托
46                             Delegate d = Delegate.CreateDelegate(tDelegate, methodHandler);
47                             //获取将要处理的事件委托
48                             MethodInfo minAddHandler = eventInfo.GetAddMethod();
49                             object[] addHandlerArgs = { d };
50                             //调用
51                             minAddHandler.Invoke(obj, addHandlerArgs);
52                             FieldInfo field = t.GetField(reflectioneventName,
53                                                         myBindingFlags);
54                             if (field != null)
55                             {
56                                 Object fieldValue = field.GetValue(obj);
57                                 if (fieldValue != null && fieldValue is Delegate)
58                                 {
59                                     Delegate objectDelegate = fieldValue as Delegate;
60                                     //动态调用
61                                     objectDelegate.DynamicInvoke(eventParameter);
62                                 }
63                             }
64                         }
65                         if (obj != null)
66                         {
67                             obj.ShowWindow();
68                             //添加已经打开的窗口 :在关闭的时候 要删除此项
69                             LoadedPlugins.Add(t.FullName);
70                         }
71                     }
72                
73                 }
74             }
75             catch (FileNotFoundException)
76             {
77                 MessageBox.Show("尊敬的用户您好!没有找到相应的模块!", "插件提示!", MessageBoxButton.OK,
78                                   MessageBoxImage.Information);
79             }
80             catch (TargetParameterCountException)
81             {
82                 MessageBox.Show("尊敬的用户您好!在调用模块时发现委托的参数不同!请检查参数的个数!", "插件提示!", MessageBoxButton.OK,
83                                 MessageBoxImage.Information);
84             }
85             catch (Exception)
86             {
87                 MessageBox.Show("尊敬的用户您好!系统发现版本与当前系统不匹配!", "插件提示!", MessageBoxButton.OK,
88                                 MessageBoxImage.Information);
89             }
90         }


本模块调用:

调用反射信息
 void Test2_Click(object sender, RoutedEventArgs e)
        {
            var item = (MenuItem)sender;
            string path = @Environment.CurrentDirectory + "\\";
            Plugin plugin = ApplicationSharedData.Plugins[item.Header.ToString()];

            ApplicationSharedData.ModulEventCommunication(this, "TestEvent", "DeleBindData", path, plugin, new object[] { "参数1", "参数2","" });
            //注 在反射TestEvent 时候 ,TestEvent有几个参数 那么S_TestEvent 也有几个参数。
            //不然会抛出异常信息,TargetParameterCountException 参数的个数不同
        }


        private static void DeleBindData(string msg, string info,string tb)
        {
            _textbox.Text = tb;
        }

此代码是我在一次开发中遇到的问题。。在这里做个备注 ,防止下次忘记了。。

 

.net企业级架构开发

posted @ 2012-12-28 17:14  在 水 一 方  阅读(2445)  评论(0编辑  收藏  举报