• 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;
            }
    复制代码
  • 相关阅读:
    laravel的workflow流程插件
    [php]laravel框架容器管理的一些要点
    laravel 自带消息notification通知
    laravel5.5的定时任务详解(demo)
    Laravel核心代码学习
    laravel 加载指定版本的mongodb
    Linux安装Composer
    composer全量镜像使用方法
    laravel在github地址
    node anyproxy ssi简易支持
  • 原文地址:https://www.cnblogs.com/dlbird/p/3974132.html
Copyright © 2020-2023  润新知