好的,所以我在玩Ninject,一个“服务层”和一个“存储库层”。
我构建了一个简单的控制台应用程序来玩,这就是我想出来的:
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
我的问题,或者我想我缺乏理解,在于模块的Main()方法:
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
为什么不这样做:
Sub Main()
Dim Service = New CustomerService(New CustomerRepository)
Console.WriteLine(Service.GetCustomerByID(710615).Name)
Console.Read()
End Sub
答案 0 :(得分:9)
基本上,您在问为什么要使用 DI容器而不是 Pure DI 。
DI实际上只是一组松散耦合的原则和模式。您可以使用这些模式组成应用程序,而不管任何特定容器。
但是,随着应用程序的复杂性增加,特别是当您需要管理组件的不同生活方式时,DI容器是一个很好的工具,可以解决您必须要解决的许多问题。手动地址。
答案 1 :(得分:4)
依赖注入允许您将对象的特定实现与其接口分离。在大多数小例子中很难证明这一点,但对于较大的系统,它可以节省生命。它还可以帮助您在单元测试中隔离对象。
例如,如果您想为CustomerService类编写测试,则可以轻松注入MockRepository而不是CustomerRepository。这样您就可以在不测试CustomerRepository的情况下测试CustomerService。
在单元测试之外,我认为最简单的可视化示例可能是您为应用程序编写数据访问模块。您可能希望支持SQL Server和MySQL。然后,您将为数据访问对象创建接口,并为两个数据库系统创建它们的特定实现。这些实现可以在运行时注入,因此:
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
这使您可以在将来添加对其他数据库的支持,将实现细节与应用程序的其余部分隔离开来。