Sunday, March 16, 2008
Time to use an Ioc (Inversion of Control) container like structuremap. Most if not all examples you find on the net are in C# but us VB.Net developers aren't imune for it either. So today I made my first project with structuremap. Lets' see how it goes. Thanks to Jeremy D. Miller for making this great product.

I used the atributes for this and not the external config file (aka: StructureMap.config).

I will demonstrate this by crating a Dal, A model and A view/presenter. Let's start with the Model

the interface

Namespace Model.Interfaces
    Public Interface IPerson
        Property Id() As Guid
        Property LastName() As String
        Property FirstName() As String
    End Interface
End Namespace

the implementation

Namespace Model
    Public Class Person
        Implements Model.Interfaces.IPerson

        Private _lastName As String
        Private _id As Guid
        Private _firstName As String

        Public Sub New()
            _id = New Guid
            _firstName = ""
            _lastName = ""
        End Sub

        Public Property FirstName() As String Implements Interfaces.IPerson.FirstName
            Get
                Return _firstName
            End Get
            Set(ByVal value As String)
                _firstName = value
            End Set
        End Property

        Public Property Id() As System.Guid Implements Interfaces.IPerson.Id
            Get
                Return _id
            End Get
            Set(ByVal value As System.Guid)
                _id = value
            End Set
        End Property

        Public Property LastName() As String Implements Interfaces.IPerson.LastName
            Get
                Return _lastName
            End Get
            Set(ByVal value As String)
                _lastName = value
            End Set
        End Property

        Public Overrides Function ToString() As String
            Return _lastName & " " & _firstName
        End Function
    End Class
End Namespace


Nothing fancy, not even pretty. But it works.

Then the dal

I start with an interface for the factory.

Imports StructureMap

Namespace Dal.Factory
    <PluginFamily("SQLServerDaoFactory", Issingleton:=True)> _
    Public Interface IDAOFactory
        ReadOnly Property Person() As Dal.Interfaces.IPerson
    End Interface
End Namespace

And here we have the first attribute for structuremap. this says that if you want an instance of this interface that you will have to look for a class with an attribute plugable and a concretekey of "SQLServerDaoFactory" in other words this is the default implementation of our interface.

Now lets look at SQLServerDAOFactory.

Imports StructureMap

Namespace Dal.SQLServer
    <Pluggable("SQLServerDaoFactory")> _
    Public Class DaoFactory
        Implements Dal.Factory.IDAOFactory

        Public ReadOnly Property Person() As Interfaces.IPerson Implements Factory.IDAOFactory.Person
            Get
                Return ObjectFactory.GetInstance(Of Interfaces.IPerson)()
            End Get
        End Property
    End Class
End Namespace
so this has a plugabble attribute with SQLServerDaoFactory as key. So this is the default implementation for IDaoFactory.

Now we will create a form with 2 labels on them and One button. Just leave the standard, this is just to show how it works. I won't even bother creating a presenter, let's talk dirty.

In the form_load event you have to add this to intialize structuremap.

StructureMapConfiguration.UseDefaultStructureMapConfigFile = False
StructureMapConfiguration.ScanAssemblies.IncludeTheCallingAssembly()

And in the button_click event you have to add this

Dim a As Model.Person
Dim d As Dal.Factory.IDAOFactory = ObjectFactory.GetInstance(Of Dal.Factory.IDAOFactory)()
a = d.Person.FindPersonbyName("")
Label1.Text = a.FirstName
Label2.Text = a.LastName

Don't forget to add structuremap.dll as a reference and to do an imports of structuremap in the form.
As you can we are doing a getinstance on ObjectFactory this will get us the default implementation of DAOFactory. Namely SQLServerDAOFactory

So why are we doing all this? Since we could have just instantiated it the normal way without a problem.

What if we now needed to have a MySQL Database instead of SQLServer? in our normal program we had to change all the references from SQLServerDAOFactory to MySQLFactory with structuremap we just change the pluginfamily default value and create a new daofactory.

this is the new daofactory.

Imports StructureMap

Namespace Dal.MySQL
    <Pluggable("MySQLDaoFactory")> _
    Public Class DaoFactory
        Implements Dal.Factory.IDAOFactory

        Public ReadOnly Property Person() As Interfaces.IPerson Implements Factory.IDAOFactory.Person
            Get
                ObjectFactory.InjectStub(GetType(Interfaces.IPerson), New MySQLPerson)
                Return ObjectFactory.GetInstance(Of Interfaces.IPerson)()
            End Get
        End Property
    End Class
End Namespace


and this is the adapted idaofactory.

Imports StructureMap

Namespace Dal.SQLServer
    <Pluggable("MySQLDaoFactory")> _
    Public Class DaoFactory
        Implements Dal.Factory.IDAOFactory

        Public ReadOnly Property Person() As Interfaces.IPerson Implements Factory.IDAOFactory.Person
            Get
                Return ObjectFactory.GetInstance(Of Interfaces.IPerson)()
            End Get
        End Property
    End Class
End Namespace


and now run the code again and see the difference in the labels. So we have low coupling and high cohesion.

Hope to see you soon for part 2




3/16/2008 3:39 PM Romance Standard Time  #    Disclaimer  |  Comments [0]  |  Trackback