Creating a database driver factory

Posts   
 
    
Devildog74
User
Posts: 719
Joined: 04-Feb-2004
# Posted on: 04-Jul-2004 20:21:59   

If you were to make the assumption that a database generic assembly generated from the northwind database would work with drivers for SQL Server, FireBird, and Oracle10; how would one create a factory so that you could create an instance of the proper data access adapter for the given driver at runtime?

Could you just do this: 1. Create 3 concrete classes named OracleDriver, SQLDriver, and FireBirdDriver. 2. Create a class the called DBDriver that derived from DataAccessAdapterBase 3. Write a constructor in the factory class that would use an enum to determine which concrete driver to create and then assign the instance of the newly create driver to the instance of the class that we are creating

Would something like this would or would there be a better way

wayne avatar
wayne
User
Posts: 611
Joined: 07-Apr-2004
# Posted on: 05-Jul-2004 09:33:25   

Hi Devildog

It's a bit of a long posting - but should help you.simple_smile

Here is a section of a factory class that i have (Non LLBLGen) - look at the Activator.CreateInstance will that not help? This is an example of activator with common ancestor classes but an example of activator with common interfaces is also possible.

The Activator can instantiate any class - so no need for any enums - mutch better when dealing with unknown class types and unknown runtime assemblies.

This factory example below constructs field objects of types:

  • CLS_BooleanField
  • CLS_DateField
  • CLS_IntegerField
  • CLS_StringField
  • I think you get the drift....
Option Strict On

Imports IIS_CL.CORE

Namespace IIS_CL.CORE
    Public Class CLS_FieldFactory

        Public Function Create_Field(ByVal FieldType As System.Type, _
                                     ByVal Owner As CLS_Base_Child_Owner, _
                                     ByVal TableName As String, _
                                     ByVal Field_Name As String, _
                                     ByVal Field_Type As System.Type, _
                                     ByVal FieldLength As Integer, _
                                     ByVal Is_Primary_Key As Boolean, _
                                     ByVal Is_Identity As Boolean, _
                                     ByVal Is_Computed As Boolean, _
                                     ByVal Is_RowGuidCol As Boolean, _
                                     ByVal Is_Nullable As Boolean, _
                                     ByVal Is_Foreign_Key As Boolean) As CLS_Field
            Dim Args(8) As Object
            Args(0) = Owner
            Args(1) = TableName
            Args(2) = Field_Name
            Args(3) = FieldLength
            Args(4) = Is_Primary_Key
            Args(5) = Is_Identity
            Args(6) = Is_Computed
            Args(7) = Is_RowGuidCol
            Args(8) = Is_Nullable
            Args(9) = Is_Foreign_Key

            .....


            Return CType(Activator.CreateInstance(FieldType, Args), CLS_Field)
        End Function

    End Class
End Namespace

Here is an example of how to load Unknown ClassTypes from Unknown Assemblies(Non LLBLGen):

    Public Function Load_Selected_Driver(ByVal DLLName As String) As System.Reflection.Assembly
        Dim Path As String = Application.ExecutablePath
        Dim DLLDriver As System.Reflection.Assembly

        Path = Path.Substring(0, Path.LastIndexOf("\"))
        DLLDriver = System.Reflection.Assembly.LoadFrom(Path + "\" + DLLName)

        Return DLLDriver
    End Function

    Private Function Load_Selected_Driver_Interface(ByVal Class_Namespace As String) As IDatabaseDriverInterface
        Dim USRControl As IDatabaseDriverInterface

        USRControl = FDLLDriver.CreateInstance(Class_Namespace)

        Return USRControl
    End Function

The other option is to use enums with a common ancestor...but this can be a pain when you don't know how many types their can be...because then you need to update the enum list the hole time.

Public Class TFruitFactory

    Public Function CreateFruit(ByVal FruitType As Integer) As TBaseFruit
        'Use a case statement here
        Select Case FruitType
            Case 0
                Return New TBananna
            Case 1
                Return New TApple
        End Select

    End Function

End Class

or maybe you could use classes with common Interfaces and enums....

Public Class IEditInterFaceFactory

    'This class only deals with construction code

    Public Function DataInterface(ByVal ObjectNo As Integer) As IEditInterface

        Select Case ObjectNo
            Case 0
                Dim Fruit As New TFruit
                Dim Fruitinterface As IEditInterface = Fruit
                Return Fruitinterface

            Case 1
                Dim Car As New TCar
                Dim CarInterface As IEditInterface = Car
                Return CarInterface

        End Select
    End Function
End Class

When using this Interface example your implementation code would look something like this:


        Dim MyDataFactory As New IEditInterFaceFactory

        Dim AbstractEditInterface As IEditInterface = MyDataFactory.DataInterface(ComboBox1.SelectedIndex)

Thats all i have for now.simple_smile

Devildog74
User
Posts: 719
Joined: 04-Feb-2004
# Posted on: 05-Jul-2004 19:18:39   

Sweet, thanks for the reply. Reflecting the type is a great idea. I can just create a DB Driver Config Section in the web.config or app.config and pass that in the constructor. Then I can switch drivers easily.

Cool, thanks again.