Reputation:
How can I create or use an event that raises when you call a shared sub/function from another object or class?
I'll show an example: I have the class DataHost that access a database:
Class DataHost
Shared Sub addName().....
Shared Sub delName().....
Shared Function getNames()....
Shared Function askPassword()........
End Class
I want the program to ask for the password every time another class calls the subs/functions of DataHost to access the database.
I could add at the beginning of each function if askpass()=False Then return
but in my code the functions are more than 20 and I would like to have a more intelligent solution.
So I am looking for something that calls askPassword()
whenever you call another sub/function.
Upvotes: 3
Views: 4941
Reputation: 2660
Alright this might not at all be what you are requesting, but I'll post the code for a shared event then you can see if you can use it in any way. (This is my log event so do overlook the naming)
Public Class Logging
Public Shared Event LogEvent As EventHandler
Public Shared Sub OnLogWrite(ByVal Sender As Object)
RaiseEvent LogEvent(Sender, New EventArgs)
End Sub
End Class
This is the shared event that you will have to listen to. You can add a handler to LogEvent wherever you want. And it will fetch all calls to this. Here you would be able to create a Shared Variable that keeps track of the Sender value. For example a List(of Object).
You raise the event anywhere (except from within a Shared
method or function, since there is no instance) with:
Logging.OnLogWrite(Me)
And you can listen to the event anywhere with:
AddHandler Logging.LogEvent, AddressOf HandleLogEvent
The code for HandleLogEvent looks like this:
Private Sub HandleLogEvent()
MessageBox.Show("Hello.")
End Sub
HandleLogEvent could for example be renamed to askPassword. Which means that if no check is made in the OnLogWrite Sub. Then Anytime the event is called, askPassword would be executed. Hope this helps you in some way.
Upvotes: 6
Reputation: 2140
i would suggest not to use shared methods for all the functions and allow them be called only through instances. Then limit the instantiation (constructor) process. a quick sample:
Class DataHost
Shared Function GetHost() As DataHost
If askPassword() Then
Return New DataHost()
End If
' Or do something else instead of throw nothing
Return Nothing
End Function
Shared Function askPassword() As Boolean
' ask for password?
End Function
''' <summary>
''' Private constructor to avoid external instantiation - thus force external calls to go through factory: GetHost()
''' </summary>
''' <remarks></remarks>
Private Sub New()
End Sub
Sub addName()
End Sub
Sub delName()
End Sub
Function getNames() As IEnumerable(Of String)
End Function
End Class
here you can see to call GetNames(), the caller has to have an instance of the DataHost, however, due to the private constructor, the caller has to get an instance of the DataHost through factory method GetHost().
and if you don't want to have many copies of DataHost, you could use singleton as well and return it out in the GetHost() method when password is provided.
EDIT: if you really want an event raised out during the process, you could do so at the GetHost method as well: create a private method in the DataHost to raise an event, then after the DataHost is instantiated, call it to throw out the event:
Shared Function GetHost() As DataHost
If askPassword() Then
dim host = New DataHost()
host.RaiseSomeEvent()
End If
' Or do something else instead of throw nothing
Return Nothing
End Function
then externally the event could be subscribed and handled.
Upvotes: 0