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;
        }
复制代码
原文地址:https://www.cnblogs.com/dlbird/p/3974132.html