Monday, October 18, 2004

VJs Tip Of The Day - October 18th 2004

Interface Based Activation

This is especially for all those early programmers who use to do Interface based programming... We use to do runtime late binding in which we came know the ProgId of the component to be created only at runtime... This use to make dynamic creation of unknown classes easy... Now in case of .Net how do we do it? It is incorrect to assume that we need assembly reference or atleast the name when you are coding the consumer class... Well here is the alternative way...

Let us take an example... I have various locations to store my data, like Xml, SQL Server, Resource File etc... Now I need to select the DataAccess at runtime based on config or registry settings or something like that and I also need to have the option of adding any other data store in the time to come.... What do I do?

(Special VB.Net edition... Kathleen, Anand M and other VB fans can all be happy... :-))


'Your data structure can be defined below
Public Structure DataEntity
Private something As integer
End Structure

'I will define an interface called IDataStore
Public Interface IDataStore
Function GetDataById(ByVal id As Integer) As DataEntity
Sub UpdateExisitingData(ByVal id As Integer, ByVal entity As DataEntity)
Function InsertNewData(ByVal entity As DataEntity) As Integer
End Interface

'Sample class to get your config settings
Public Class GetConfigValues
Public Shared Function GetConfig(ByVal key As String) As String
'This will go at runtime to some config place to get the details as per the key passed
'If your company is using SQL as datastore then it can get connection string as param
'and the SQL access class as the class name and so on...
If (key.ToLower().Equals("constructorparam")) Then
Return String.Empty
ElseIf (key.ToLower().Equals("classname")) Then
Return "AssemblyName.ClassnName"
End If
End Function
End Class

'Below is the generic class which exposes the Interface in a special way
Public Class GenericDataAccess

Private objRuntimeStore As IDataStore
Public Sub New()
Dim objConstructParams(0) As Object
'GetConfigValues is your custom class to get your config settings
objConstructParams(0) = GetConfigValues.GetConfig("ConstructorParam")
'The class name should have the fully qualified name i.e. the assembly name too
Dim storeClassFullName As String = GetConfigValues.GetConfig("ClassName")
objRuntimeStore = CType(Activator.CreateInstance(Type.GetType(storeClassFullName, _
False, True), objConstructParams), _
IDataStore)
End Sub


Public Function GetDataById(ByVal id As Integer) As DataEntity
Return objRuntimeStore.GetDataById(id)
End Function

Public Sub UpdateExisitingData(ByVal id As Integer, ByVal entity As DataEntity)
objRuntimeStore.UpdateExisitingData(id, entity)
End Sub

Public Function InsertNewData(ByVal entity As DataEntity) As Integer
Return objRuntimeStore.InsertNewData(entity)
End Function
End Class



PS: The code and example is just to demonstrate one of the way by which you can hook up with a class at runtime... Do not consider this to be ideal design methodology or coding practice example... If you write back to me saying this can be better done in x or y way all I can do is probably agree with you... :-), but it would be nice if see this as a solution to a very specific problem...

No comments: