EventInfo.AddEventHandler question

Z

Zoury

Hi folks ! :O)

Let's say I have the following EventHandler defined in a class :
'***
Option Explicit On

Public Delegate Sub MyEventHandler(ByVal sender As Object, ByVal e As
MyEventArgs)

Public NotInheritable Class MyEventArgs
Inherits EventArgs

Private m_nValue As Int32

Public Property Value() As Int32
Get
Return m_nValue
End Get
Set(ByVal Value As Int32)
m_nValue = Value
End Set
End Property

End Class

Public NotInheritable Class MyEventThrower

Public Event MyEvent As MyEventHandler

Public Sub MyThrowEventSub()

Dim e As New MyEventArgs
RaiseEvent MyEvent(Me, e)
Console.WriteLine(e.Value)

End Sub

End Class
'***

How would one use the EventInfo.AddEventHandler() method in order to catch
this event ?

Here's the sample code i tried that failed miserably :
'***
Private Sub Form1_Load( _
ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles MyBase.Load

Dim a As [Assembly] = [Assembly].LoadFile("C:\MyAssembly.dll")
Dim t As Type = a.GetType(String.Format("{0}.MyEventThrower", _
a.GetName().Name))
Dim o As Object = Activator.CreateInstance(t)
Dim ev As EventInfo = t.GetEvent("MyEvent")
Dim handler As [Delegate] = _
[Delegate].CreateDelegate(ev.EventHandlerType, _
Me,
"MyEventHandler")

ev.AddEventHandler(o, handler)
t.InvokeMember("MyThrowEventSub", _
BindingFlags.Public Or _
BindingFlags.InvokeMethod Or _
BindingFlags.Instance, _
Nothing, o, Nothing)
ev.RemoveEventHandler(o, handler)

End Sub

' this doesn't not compile since MyEventArgs is not defined..
'Public Sub MyEventHandler(ByVal sender As Object, ByVal e As
MyEventArgs)
' e.Value = 15
'End Sub
'***

Thanks in advance for any ideas.
 
A

Armin Zingler

Zoury said:
' this doesn't not compile since MyEventArgs is not defined..
'Public Sub MyEventHandler(ByVal sender As Object, ByVal e As
MyEventArgs)
' e.Value = 15
'End Sub
'***


Set a reference to the dll. As you use the type 'MyEventArgs', it must be
declared.


Armin
 
Z

Zoury

Hi Armin ! :O)
Set a reference to the dll. As you use the type 'MyEventArgs', it must be
declared.

What if we don't want or can't set any reference to the dll ?
If i had a reference to the dll in the first place i wouldn't need to use
reflection at all. ;O)


For the records, I did it by declaring the MyEventHandler with an EventArgs
parameter type like this (Object would have worked to..) :
'***
Public Delegate Sub MyEventHandler(ByVal sender As Object, ByVal e As
EventArgs)

Public NotInheritable Class MyEventArgs
Inherits EventArgs

Private m_nValue As Int32

Public Property Value() As Int32
Get
Return m_nValue
End Get
Set(ByVal Value As Int32)
m_nValue = Value
End Set
End Property

End Class

Public NotInheritable Class MyEventThrower

Public Event MyEvent As MyEventHandler

Public Sub MyThrowEventSub()

Dim e As New MyEventArgs
RaiseEvent MyEvent(Me, e)
Console.WriteLine(e.Value)

End Sub

End Class
'***

I can now use whatever member of the MyEventArgs class instance using
reflection on the caller side like this :
'***
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles MyBase.Load

Dim a As [Assembly] =
[Assembly].LoadFile("c:\LoadAssemblyAndAddHandlerLibrary.dll")
Dim t As Type = a.GetType(String.Format("{0}.MyEventThrower",
a.GetName().Name))
Dim o As Object = Activator.CreateInstance(t)
Dim ev As EventInfo = t.GetEvent("MyEvent")
Dim handler As [Delegate] =
[Delegate].CreateDelegate(ev.EventHandlerType, Me, "MyEventHandler")

ev.AddEventHandler(o, handler)
t.InvokeMember("MyThrowEventSub", _
BindingFlags.Public Or _
BindingFlags.InvokeMethod Or _
BindingFlags.Instance, _
Nothing, o, Nothing)
ev.RemoveEventHandler(o, handler)

End Sub

Public Sub MyEventHandler(ByVal sender As Object, ByVal e As EventArgs)

Dim a As [Assembly] =
[Assembly].LoadFile("c:\LoadAssemblyAndAddHandlerLibrary.dll")
Dim t As Type = a.GetType(String.Format("{0}.MyEventArgs",
a.GetName().Name))
Dim p As PropertyInfo = t.GetProperty("Value")
p.SetValue(e, 15, Nothing)

End Sub
'***
 
A

Armin Zingler

Zoury said:
Hi Armin ! :O)


What if we don't want or can't set any reference to the dll ?
If i had a reference to the dll in the first place i wouldn't need
to use reflection at all. ;O)


How can you know the signature at devlopment time if type information is
discovered at run time?

The contradiction is: You say you don't have type information, that's why
you load it at run time. On the other side, you say, you do have some
information, that's why you know how to declare the event handler.

I think you took the wrong approach. If you do know the signature - or
whatever piece of information - write a base library containing base
classes or interfaces. Reference the base library. Load and create instances
using reflection from any assembly. Determine if the base interfaces are
supported or if the objects are derived from a base class (If typeof ...
is). If they are, assign the objects to variables of types declared in the
base library. Then you can also handle their events.


Armin
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top