Ok, so I was playing around with Ninject, a "Service Layer" and a "Repository Layer".
I built a simple console application to to play around, this is what I came up with:
Imports Ninject
Module Module1
Sub Main()
Dim Kernel As IKernel = New StandardKernel(New CustomerModule)
Dim Service = Kernel.Get(Of CustomerService)()
Console.WriteLine(Service.GetCustomerByID(1).Name)
Console.Read()
End Sub
End Module
#Region "Services"
Public Class CustomerService
Private _Repository As ICustomerRepository
<Inject()> _
Public Sub New(ByVal Repository As ICustomerRepository)
_Repository = Repository
End Sub
Public Function GetCustomerByID(ByVal ID As Integer) As Customer
Return _Repository.GetByID(ID)
End Function
End Class
#End Region
#Region "Repositories"
Public Interface IRepository(Of T)
Function Query(ByVal Predicate As Expressions.Expression(Of Func(Of T, Boolean))) As IQueryable(Of T)
Function GetByID(ByVal ID As Integer) As T
End Interface
Public Interface ICustomerRepository
Inherits IRepository(Of Customer)
End Interface
Public Class CustomerRepository
Implements ICustomerRepository
Public Function GetByID(ByVal ID As Integer) As Customer Implements IRepository(Of Customer).GetByID
Return New Customer With {.ID = ID, .Name = "Sam Striano"}
End Function
Public Function Query(ByVal Predicate As System.Linq.Expressions.Expression(Of System.Func(Of Customer, Boolean))) As System.Linq.IQueryable(Of Customer) Implements IRepository(Of Customer).Query
Return Nothing
End Function
End Class
#End Region
#Region "Domain Objects"
Public Class Customer
Public Property ID As Integer
Public Property Name As String
End Class
#End Region
#Region "Ninject Modules"
Public Class CustomerModule
Inherits Modules.NinjectModule
Public Overrides Sub Load()
Bind(Of ICustomerRepository).To(Of CustomerRepository)()
End Sub
End Class
#End Region
My question, or I guess my lack of understanding, lies in Main() method of the module:
Sub Main()
Dim Kernel As IKernel = New StandardKernel(New CustomerModule)
Dim Service = Kernel.Get(Of CustomerService)()
Console.WriteLine(Service.GetCustomerByID(710615).Name)
Console.Read()
End Sub
Why not just do this:
Sub Main()
Dim Service = New CustomerService(New CustomerRepository)
Console.WriteLine(Service.GetCustomerByID(710615).Name)
Console.Read()
End Sub
The injector class injects dependencies broadly in three ways: through a constructor, through a property, or through a method. Constructor Injection: In the constructor injection, the injector supplies the service (dependency) through the client class constructor.
Of course. If you have a really small project with 12 classes, then a DI framework is almost certainly overkill.
One problem with constructor injection is that if your class has many dependencies, then your constructor signature gets unwieldy and hard to read. Now, when you have multiple dependencies that you need to inject, each one is a separate set method and so we don't have a long list of constructor parameters.
Basically, you are asking why you should use a DI Container instead of Pure DI.
DI is really just a set of principles and patterns that enable loose coupling. You can use those patterns to compose an application irrespective of any particular container.
However, as an application grows in complexity, and particularly when you need to manage differing lifestyles of your components, a DI Container is an excellent tool that addresses many issues that you'd otherwise have to address manually.
Dependency injection lets you decouple specific implementations of objects from their interfaces. It is difficult to justify in most of the small examples out there, but for larger systems it can be a life-saver. It can also help you to isolate your objects in unit tests.
For example, if you wanted to write tests for your CustomerService class, you could easily inject a MockRepository instead of CustomerRepository. This would let you test CustomerService without also testing CustomerRepository.
Outside of unit testing, I think the easiest example to visualize might be if you were writing a data access module for your application. You might want to support SQL Server and MySQL. You would then create Interfaces for your data access objects and create specific implementations of them for both database systems. Those implementations could be injected at runtime, thusly:
Function Setup(ByVal dbType As String) As IKernel
Dim dbModule As NinjectModule
If dbType = "SQL Server" Then
dbModule = New SQLServerModule
Else If dbType = "MySQL" Then
dbModule = New MySQLModule
End If
Return New StandardKernel(dbModule)
End Function
This also enables you to add support for other databases in the future, isolating the implementation details from the rest of the application.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With