• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 165
  • Last Modified:

Event raised before object is set

Hello,

I wrote an activex DLL that holds a class which handles connecting to an Access or SQLServer DB.
the class has different properties like DB password, Save DB path to registry, etc.
the only public function is this:

   Public Function CreateConnection(Optional DBPath As String) As ADODB.Connection
   .
   .
   .
   end function

which handles the all connection operation and as you can see it returns a connection object to set the one in the application that uses this activex.

my problem is that im raising a Connection_Successful event in the CreateConnection function/
If i try writing a code that accesses the database in the sub that handles this event  using my connection object i get an error that my object is not set which is true since the CreateConnection function didnt return the object yet.

is there a way to make the Connection_Successful event raise after the function that raised it has returned the object?

Thank you.
0
unholly_plugin
Asked:
unholly_plugin
  • 4
  • 2
  • 2
1 Solution
 
jkaiosCommented:
In your CreateConnection() function, you first test if the connection was, in fact, successful by testing the "State" property and then pass the Connection Object to a parameter in your Connection_Successful event.

1) Your Connection_Successful event should be declared like this:

   Public Event Connection_Successful(ConnObject As ADODB.Connection)

2) In your CreateConnection function, your codes should be like this:

   Public Function CreateConnection(SQLServerName As String, DBName As String) As ADODB.Connection
      Dim oConn As New ADODB.Connection
      With oConn
         .Provider = "SQLOLEDB"
         .Properties("Persist Security Info").Value = False
         .Properties("Integrated Security") = "SSPI"
         .Properties("Data Source").Value = SQLServerName
         .Properties("Initial Catalog").Value = DBName
         .Open      
         If .State = adStateOpen Then
            RaiseEvent Connection_Successful(oConn)
         End If
      End With
   End Function
0
 
jkaiosCommented:
By the way, "underscores" are allowed in Event names so you would have to remove the "_" from your "Connection_Successful" event.
0
 
jkaiosCommented:
... or try this one:

   Public Function CreateConnection(SQLServerName As String, DBName As String) As ADODB.Connection
      Dim oConn As New ADODB.Connection
      With oConn
         .Provider = "SQLOLEDB"
         .Properties("Persist Security Info").Value = False
         .Properties("Integrated Security") = "SSPI"
         .Properties("Data Source").Value = SQLServerName
         .Properties("Initial Catalog").Value = DBName
         .Open      
         If .State = adStateOpen Then
            Set CreateConnection = oConn
         End If
      End With
   End Function
0
Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
unholly_pluginAuthor Commented:
Hey jkaios, thanks for the quick answer.

I have already thought about sending the object with the Success event, but is it not considered redundant??? returning the object with the event and also with the function???

If its not then this is the obvious solution, i was just wondering if it was possible to have it like i did and make the event raise a bit later when the connection object is already set.

Thanks again
0
 
jkaiosCommented:
Yeah, that's kinda redundant, but that was just a quick example on how to resolve the issue.

In my first example, I was referring to a function that returns a Boolean value instead of an ADODB.Connection object because the object is already returned by the custom event, in which you're right.  We don't have to return the object twice via both the event and the function.

In the second example, the function returns an ADO Connection object which is only set after the connection was in fact successful. Otherwise, it would return an ADO Connection object which is set to Nothing if the connection was not successful.
0
 
ronkleinCommented:
consider redesign your object model.
i'd return a connection object, and it's up to the client to invoke the connection's "Open" method, and then listening to the connection's events is up to the client as well.
imho, raising an event and passing the connection object as an argument is not a good design.
0
 
unholly_pluginAuthor Commented:
hey ronklein,

id agree about not passing the connection object with the event
but id still want someone who uses my class to get a notification about the success or failure of the CreateConnection method.

what if i exposed a connection object as public from my class and change CreateConnection to a sub. then when the success event is raised someone who ueses the class will be able to use the connection object i exposed and connected to the db with the parameters given to the class object?

any thoughts about that?
0
 
ronkleinCommented:
Hi again,

There are several solutions to your problem. All of them are based on design patterns (you may want to read about it some day), but to make things easier, I will not confuse you with the specific names and terminology.

The first solution is to write the CreateConnection function, which accepts a reference to the caller. The caller itself must implement an interface that you can write, which has a single function, named CreationCompleted, with 2 arguments: a connection object, which may be Nothing, if something went wrong, and a string which describes the error that occurred (if any).
[Interfaces are a better than events, when it comes to performance]
So, the first solution is basically indication via callback and interface.

The second solution is, as you suggested, to expose the connection itself, but with a "smart" way rather than just a public connection.
I think that a property get is better than a get/set.

To make thing a bit clearer for the first solution, I uploaded a zip file to my own site. You can download the file within 30 days or so. After that period the file will be removed from my site:
http://www.ronklein.co.il/vb_connection.zip


Best,

Ron
0

Featured Post

Upgrade your Question Security!

Add Premium security features to your question to ensure its privacy or anonymity. Learn more about your ability to control Question Security today.

  • 4
  • 2
  • 2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now