I don’t see much talk of interface programming/development these days so I thought an example might help someone. All that is written here applies equally to all the Microsoft .Net languages (VB.Net, C#.Net, etc…) and the different types of software graphical user interfaces, ASP.Net web sites, Windows services, etc…).
What is an interface? In basic terms, an interface is a contract that specifies some specifics that a class is agreement to implement/support.
There are occasionally cases where a particular chunk of code is handed a wide range of object types to process. An example is a service that saves data to a database. All forms of data that must be saved must go thru this service. The easy approach in this case is for all the classes that are able to be saved to implement an interface (in the following examples, “IPersistToDB”). The generic code then confirms that the object supports this interface and, if so, calls the routine.
In the following sample code, the interface is title “IPersistToDb” and requires a “Save” routine with an input parameter of type string (which is the connection string to the database).
Public Interface IPersistToDB
Sub Save(ByVal ConnectionString As String)
End Interface
A class would implement this interface by using an “Implements” statement in the class declaration.
Public Class Invoice
Implements IPersistToDB
When the above Implements statement is added, Visual Studio automatically creates the interface implementation. You must then fill in the details.
Public Sub Save() Implements IPersistToDB.Save
‘ Do something
End Sub
That is all pretty straight forward stuff.
The less documented part is using that interface to call a method on an object.
The first thing that is helpful is a common routine to test an object to determine if it supports a particular interface. This routine will do that work for you. It simply retrieves the names of the interfaces that the object supports and then compares them to the name of the interface that we are looking for.
Public Function SupportsInterface(ByVal pInterfaceName As String,
ByVal pObject As Object) As Boolean
Dim interfaceArray As Array
Dim oType As Type
interfaceArray = pObject.GetType.GetInterfaces
For Each oType In interfaceArray
If oType.Name.ToLower = pInterfaceName.ToLower Or
oType.FullName.ToLower = pInterfaceName.ToLower Then
Return True
End If
Next
‘If interface found, we returned true above
Return False
End Function
Once the above is done and returns true, you can safely call the routine of interest and supply the necessary parameter(s).
If SupportsInterface(“IPersistToDB”, pObject) Then
pObject.Save(“ConnectionString”)
End If
Easy enough. However; a much better example is when the routine expects multiple parameters OR you do not want to hard code the routine name. It is common to have all of this defined in configuration data. The code is then very dynamic based on the configuration information. This functionality uses Reflection to call the routine. What is Reflection? In simple terms, it allows code to discover and utilize object type information at runtime. The big benefit in this example is the ability to NOT hardcode routine names. Of course, you can create if..else or case statements and handle your existing possible scenarios but what happens when you add another scenario? Yup, you have to edit your code. Using something similar to the example below allows you to add additional scenarios without editing your code (within reason).
If SupportsInterface(“InterfaceName”, pObject) Then
Dim args As Object()
args = New Object() {“parameter1Value”,
“parameter2Value”,
“parameter3Value”}
pObject.GetType.InvokeMember(ConfigData.RoutineName,
Reflection.BindingFlags.InvokeMethod,
Nothing, pObject, args, Thread.CurrentThread.CurrentCulture)
End If
This is just barely touching the basics of interface programming. It is an rather large area that contains a huge amount of functionality that is very much worth understanding and investing time to learn.
Leave a Reply