C#反射调用其它DLL的委托事件 传值
C#反射调用其它DLL的委托事件 传值
在插件式开发。我们要调用其它插件或模块的委托事件时、那么我们需要通过反射。
复制代码
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();
}
}
}
复制代码
复制代码
/// <summary>
/// 模块之间 委托事件 通信
/// </summary>
/// <param name="currentWindow">当前的Window</param>
/// <param name="reflectioneventName">要反射模块中的 委托事件名称</param>
/// <param name="currentEventName">在当前类中要执行的事件名称</param>
/// <param name="filePath">反射文件的路经</param>
/// <param name="plugin">插件</param>
/// <param name="eventParameter">通信的消息</param>
public static void ModulEventCommunication(Window currentWindow, string reflectioneventName, string currentEventName, string filePath, Plugin plugin, object[] eventParameter)
{
if (reflectioneventName == null)
throw new ArgumentNullException("reflectioneventName");
if (currentEventName == null)
throw new ArgumentNullException("currentEventName");
if (filePath == null)
throw new ArgumentNullException("filePath");
if (eventParameter == null)
throw new ArgumentNullException("eventParameter");
try
{
Assembly assembly = Assembly.LoadFrom(filePath + plugin.NameSpace + "." + plugin.Exends);
Type[] type = assembly.GetTypes();
foreach (Type t in type)
{ //主要是判断该窗口是否实现 IElementsView 如果没有实现 就不需要反射或者不是插件
if (t.GetInterface("IElementsView") != null && t.Name == plugin.ClassName)
{
//注:在这里要判断是否已经加载:
if (LoadedPlugins.Contains(t.FullName))
{
return;
}
//反射执行的成员和类型搜索
const BindingFlags myBindingFlags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static;
EventInfo eventInfo = t.GetEvent(reflectioneventName, myBindingFlags);
//获取到当前的类
var obj = (IElementsView)assembly.CreateInstance(t.FullName);
if (eventInfo != null)
{
Type tDelegate = eventInfo.EventHandlerType;
MethodInfo methodHandler = currentWindow.GetType().GetMethod(currentEventName,myBindingFlags);
//创建委托
Delegate d = Delegate.CreateDelegate(tDelegate, methodHandler);
//获取将要处理的事件委托
MethodInfo minAddHandler = eventInfo.GetAddMethod();
object[] addHandlerArgs = { d };
//调用
minAddHandler.Invoke(obj, addHandlerArgs);
FieldInfo field = t.GetField(reflectioneventName,myBindingFlags);
if (field != null)
{
Object fieldValue = field.GetValue(obj);
if (fieldValue != null && fieldValue is Delegate)
{
Delegate objectDelegate = fieldValue as Delegate;
//动态调用
objectDelegate.DynamicInvoke(eventParameter);
}
}
}
if (obj != null)
{
obj.ShowWindow();
//添加已经打开的窗口 :在关闭的时候 要删除此项
LoadedPlugins.Add(t.FullName);
}
}
}
}
catch (FileNotFoundException)
{
MessageBox.Show("尊敬的用户您好!没有找到相应的模块!", "插件提示!", MessageBoxButton.OK,
MessageBoxImage.Information);
}
catch (TargetParameterCountException)
{
MessageBox.Show("尊敬的用户您好!在调用模块时发现委托的参数不同!请检查参数的个数!", "插件提示!", MessageBoxButton.OK,
MessageBoxImage.Information);
}
catch (Exception)
{
MessageBox.Show("尊敬的用户您好!系统发现版本与当前系统不匹配!", "插件提示!", MessageBoxButton.OK,
MessageBoxImage.Information);
}
}
复制代码
本模块调用:
复制代码
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;
}
复制代码

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

C#反射调用其它DLL的委托事件 传值的更多相关文章
- C#反射调用外部Dll,执行其中异步函数并取返回值
using System.Reflection; 1.载入Dll Assembly asm=Assembly.LoadFile(FullPath);//FullPath 为Dll所在位置的全路径. 2 ...
- 反射调用发生错误信息 LoadNeither
错误信息: Service cannot be started. System.Reflection.TargetInvocationException: Exception has been thr ...
- 外壳exe通过反射调用dll时
外壳exe通过反射调用dll时,dll是 4.0的框架,外壳exe也需要编译成4.0的框架,如果dll本身有调用32位的dll,那么外壳exe也需要编译成32位. 调试时报的那个错,直接继续运行,不影 ...
- QT编写DLL给外部程序调用,提供VC/C#/C调用示例(含事件)
最近这阵子,接了个私活,封装一个开发包俗称的SDK给客户调用,查阅了很多人家的SDK,绝大部分用VC编写,而且VC6.0居多,估计也是为了兼容大量的XP用户及IE浏览器,XP自带了VC6.0运行库,所 ...
- 反射调用DLL
public static type GetClassType(string ClassName,string dllname) { Type ClassType =null; foreach(Ass ...
- 利用反射--调用一个按钮的Click事件
最基本的调用方法 (1)button1.PerformClick();(2)button1_Click(null,null);(3)button_Click(null,new EventArgs()) ...
- C# 反射调用私有事件
原文:C# 反射调用私有事件 在 C# 反射调用私有事件经常会不知道如何写,本文告诉大家如何调用 假设有 A 类的代码定义了一个私有的事件 class A { private event EventH ...
- 2019-11-29-C#-反射调用私有事件
原文:2019-11-29-C#-反射调用私有事件 title author date CreateTime categories C# 反射调用私有事件 lindexi 2019-11-29 08: ...
- 2019-8-30-C#-反射调用私有事件
title author date CreateTime categories C# 反射调用私有事件 lindexi 2019-08-30 08:52:57 +0800 2018-09-19 20: ...
随机推荐
- 36纯 CSS 动画原理,在页面上表现日蚀现象
原文地址:https://segmentfault.com/a/1190000015070543 感想: 动画,背景颜色 HTML code: <div class="sky" ...
- Linux文件浏览命令
1.cat 命令 快快捷查看当前文件的内容.cat适合查看少量信息的文件 cat file 2.more 命令 分页显示文件内容 more file 操作: enter ...
- sql(Oracle)优化之索引
原文:https://www.cnblogs.com/oraclestudy/articles/5779210.html 建立索引的目的是:l 提高对表的查询速度:l 对表有关列的取值进行检查. 注意 ...
- Apache-Axis小结
以前用过axis, 不过好久不弄, 有忘记了.很多很多东西放在收藏夹里面, 但是长时间不去看,结果就是还是不熟悉!现在再简单总结一下吧. Axis开发服务器端webservice其实很简单. 1 下载 ...
- spark 数据读取与保存
spark支持的常见文件格式如下: 文本,json,CSV,SequenceFiles,Protocol buffers,对象文件 1.文本 只需要使用文件路径作为参数调用SparkContext 中 ...
- JavaScript 字符串拼接 & setInterval()实现简单动画
在学习JavaScript DOM编程艺术第十章时,遇到了一个小问题: 想要实现的最终效果:一个小方块不断的向下移动. 小方块绝对定位,设置好top与left值后,写了一个动态获取方块到上方距离并在每 ...
- 白鹭引擎 - 本地坐标和舞台坐标的转化 ( globalToLocal, localToGlobal )
class Main extends egret.DisplayObjectContainer { /** * Main 类构造器, 初始化的时候自动执行, ( 子类的构造函数必须调用父类的构造函数 ...
- python中pop()函数的用法
pop() 函数用于移除列表中的一个元素(默认最后一个元素),并且返回该元素的值. 语法:list.pop(obj=list[-1]) //默认为 index=-1,删除最后一个列表值. obj -- ...
- Tesseract-OCR4.0版本在VS2015上的编译与运行(转)
最近刚开始接触识别库引擎方面的知识,由于项目中需要使用光学识别处理模块,在老师与朋友的推荐下,我开始接触tesseract光学识别库,在最开始从GitHub上下载的源代码进行编译的时候,出现了许多意想 ...
- 学习笔记2:postman 的基本使用
1.get 请求 请求接口:http://xx.xx.xx.xx/api/user/stu_info 请求参数:stu_name 请求参数是放在请求 URL 里的,点击 Params添加参数,key ...