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 NamespaceNothing 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 NamespaceAnd 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 Namespaceso 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.LastNameDon'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 Namespaceand 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 Namespaceand 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