简体   繁体   中英

vb.net dll reflection event

I'm trying to pass a user defined event argument class from a dll to my main program. Both have the event argument class defined, but when I try to bind the event delegate to the method it won't bind because its signature is not compatible. I've stripped the code down to the main problem.

The code in the dll raises an event called ValueChange with a ValueEventArgs as argument:

Public Class Main
  Public Event ValueChange(ByVal sender As System.Object, ByVal e As ValueEventArgs)
  Private _Value As Integer

  Public Sub Up()
    _Value += 1
    RaiseEvent ValueChange(Me, New ValueEventArgs(_Value))
  End Sub
End Class

Public Class ValueEventArgs
  Inherits System.EventArgs
  Public Property Value As Integer

  Public Sub New(ByVal Value As Integer)
    Me.Value = Value
  End Sub
End Class

The Main program loads the dll and binds the event delegate to the method ShowValue:

Imports System.Reflection

Public Class Main
  Private DriverAssembly As [Assembly]
  Private DriverClass As Type
  Private DriverClassInstance As Object

  Private Sub ButtonLoad_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ButtonLoad.Click
    DriverAssembly = [Assembly].Load("reflection_event, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null")
    DriverClass = DriverAssembly.GetType("ReflectionEventDll.Main")
    DriverClassInstance = Activator.CreateInstance(DriverClass)

    ' get the handler method
    Dim Method As MethodInfo = Me.GetType.GetMethod("ShowValue")

    ' get the event and create a delegate
    Dim ValueChangeEvent As EventInfo = DriverClass.GetEvent("ValueChange")
    Dim Handler As [Delegate] = [Delegate].CreateDelegate(ValueChangeEvent.EventHandlerType, Me, Method) ' Fails
    ' Cannot bind to the target method because its signature or security transparency is not compatible with that of the delegate type.

    ' add the event handler
    ValueChangeEvent.AddEventHandler(DriverClassInstance, Handler)
  End Sub

  Private Sub ButtonUp_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ButtonUp.Click
    DriverClass.GetMethod("Up").Invoke(DriverClassInstance, Nothing) ' invoke the method on the driver class instance
  End Sub

  Public Sub ShowValue(ByVal sender As Object, ByVal e As ValueEventArgs)
    MessageBox.Show(e.Value.ToString())
  End Sub
End Class

Public Class ValueEventArgs
  Inherits System.EventArgs
  Public Property Value As Integer

  Public Sub New(ByVal Value As Integer)
    Me.Value = Value
  End Sub
End Class

If I remove the creation of the delegate and the AddEventHandler everything works without a problem, without the event of course.

Funny thing, if I change the arguments of ShowValue method in the main program everything suddenly works, including the event.

Public Sub ShowValue(ByVal sender As Object, ByVal e As EventArgs)
  ' works, but the Value is lost
End Sub

It gets better, because it's not completely lost. If I put a breakpoint on the Sub I can see e is containing a property called Value.
A DirectCast also fails, but writing the EventArgs to a Object seems to work.

  Public Sub ShowValue(ByVal sender As Object, ByVal e As EventArgs)
    Dim Obj As Object = e
    MessageBox.Show(Obj.Value.ToString())
  End Sub

It works, but I don't think this is the right way. How can I use a user defined event argument class when handling an event from a dll?

I've reached a solution with help of this answer . I feel like this is the best solution at the moment and it produces usable errors if it fails.

The code in the dll and the binding of the method stay unchanged, but the called method now uses reflection to get the Value property. Ported to VB.net the method looks like this:

  Public Sub ShowValue(ByVal sender As Object, ByVal e As EventArgs)
    Dim ValueProperty As PropertyInfo = e.GetType().GetProperty("Value")
    Dim Value As Integer = Convert.ToInt32(ValueProperty.GetValue(e, Nothing))

    MessageBox.Show(Value.ToString())
  End Sub

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM