Contents
Introduction
This article is going to discuss two ways of displaying the DataLinks dialog to facilitate user entry of connection strings. The code you will see here is from a minimalist’s perspective, since I myself like to write as few lines and include as little code as possible to get the job done. I will show two approaches available to VB.net developers to include the DataLinks dialog without the need include any additional references. (aaaha you guessed it late-binding)
Most applications today use some means of persisting data, and to this end the relational database is the method of choice. DotNet developers know that in order to anything with a relational database you must first be able to connect to that database.
The DataLinks object is a COM component. So you can, if you want, create interop stubs through Visual Studio or manually through TlbImp.exe. Doing one of these makes it easy to write code that makes use of the COM component, however in order to keep my code as thin as possible I chose not include any references nor add any interop stub files to my project. Instead, the DataLinks component is created through late-binding and methods are invoked via reflection.
As an additional exercise I thought it would be useful to demonstrate the two types of reflection available to VB.net developers.
VB6 developers should be familiar with CreateObject and CallByName functions. These functions gave VB6 developers the flexibility to create objects and invoke methods using strings. Microsoft made the decision to keep these functions as part of the .Net framework so they can be used to perform dynamic invocation. With .Net came a very powerful reflection api. Through the use of various classes in the System.Reflection namespace and the Type and Activator classes, these same operations (and more) can be performed.
The code is short and pretty much self explanatory. So without further adieu:
Top 
Code
Private Sub VB6StyleReflection()
Dim dlink As Object = CreateObject("Datalinks")
CallByName(dlink, "hWnd", CallType.Let, Me.Handle.ToInt32)
If txtConnectionString.Text = String.Empty Then
Dim conn As Object = CallByName(dlink, "PromptNew", CallType.Method)
If Not Object.Equals(conn, Nothing) Then
txtConnectionString.Text = CType(CallByName(conn, "ConnectionString", CallType.Get), String)
System.Runtime.InteropServices.Marshal.ReleaseComObject(conn)
End If
Else
Dim conn As Object = CreateObject("ADODB.Connection")
CallByName(conn, "ConnectionString", CallType.Let, txtConnectionString.Text)
If CType(CallByName(dlink, "PromptEdit", CallType.Method, conn), Boolean) Then
txtConnectionString.Text = CType(CallByName(conn, "ConnectionString", CallType.Get), String)
End If
System.Runtime.InteropServices.Marshal.ReleaseComObject(conn)
End If
System.Runtime.InteropServices.Marshal.ReleaseComObject(dlink)
End Sub
Private Sub DotNetStyleReflection()
Dim dlinkType As Type = Type.GetTypeFromProgID("Datalinks", True)
Dim dlink As Object = Activator.CreateInstance(dlinkType)
dlinkType.InvokeMember("hWnd", BindingFlags.SetProperty Or
BindingFlags.Public Or BindingFlags.Instance,
Nothing,
dlink,
New Object() {Me.Handle.ToInt32})
If txtConnectionString.Text = String.Empty Then
Dim conn As Object = dlinkType.InvokeMember("PromptNew",
BindingFlags.InvokeMethod Or BindingFlags.Public Or BindingFlags.Instance ,
Nothing,
dlink,
Nothing)
If Not Object.Equals(conn, Nothing) Then
Dim connType As Type = conn.GetType()
txtConnectionString.Text = DirectCast(connType.InvokeMember("ConnectionString",
BindingFlags.GetProperty Or BindingFlags.Instance Or BindingFlags.Public,
Nothing,
conn,
Nothing), String)
System.Runtime.InteropServices.Marshal.ReleaseComObject(conn)
End If
Else
Dim connType As Type = Type.GetTypeFromProgID("ADODB.Connection", True)
Dim conn As Object = Activator.CreateInstance(connType)
connType.InvokeMember("ConnectionString",
BindingFlags.SetProperty Or BindingFlags.Instance Or BindingFlags.Public,
Nothing,
conn,
New Object() {txtConnectionString.Text})
If DirectCast(dlinkType.InvokeMember("PromptEdit",
BindingFlags.InvokeMethod Or BindingFlags.Public Or BindingFlags.Instance,
Nothing,
dlink, New Object() {conn}),
Boolean) Then
txtConnectionString.Text = DirectCast(connType.InvokeMember("ConnectionString",
BindingFlags.GetProperty Or BindingFlags.Instance Or
BindingFlags.Public,
Nothing,
conn,
Nothing), String)
End If
System.Runtime.InteropServices.Marshal.ReleaseComObject(conn)
End If
System.Runtime.InteropServices.Marshal.ReleaseComObject(dlink)
End Sub
Top 
Conclusion
Obviously instantiating COM objects this way is going to save you from having to declare the reference, but for that bit it buys you there is a price. The costs are dynamic invocation is more error prone, and executes more slowly than early bound code. In this case I think these costs are acceptable because a little additional testing can flush out any issues in this small bit of code, and since this is a UI component that would likely not be used frequently a few extra tenths of a second will likely not be an issue.
Top 
Refrences
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vbcn7/html/vbconcallingpropertyormethodusingstringname.asp [^] http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/frlrfsystemreflection.asp [^]
Top 
Connection String Information:
http://www.connectionstrings.com/ [^] http://www.sqlstrings.com/ [^]
http://www.carlprothman.net/Default.aspx?tabid=81 [^]Top 