依赖注入 - 我不明白!

Sam*_*Sam 5 vb.net dependency-injection ninject

好吧,所以我正在玩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
Run Code Online (Sandbox Code Playgroud)

我的问题,或者我猜我缺乏理解,在于模块的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
Run Code Online (Sandbox Code Playgroud)

为什么不这样做:

Sub Main()
    Dim Service = New CustomerService(New CustomerRepository)
    Console.WriteLine(Service.GetCustomerByID(710615).Name)
    Console.Read()

End Sub
Run Code Online (Sandbox Code Playgroud)

Mar*_*ann 9

基本上,你在问为什么你应该使用DI容器而不是Pure DI.

DI实际上只是一能够实现松散耦合的原则和模式.无论任何特定容器如何,您都可以使用这些模式组成应用程序.

但是,随着应用程序的复杂性增加,特别是当您需要管理组件的不同生活方式时,DI Container是一个出色的工具,可以解决您必须手动解决的许多问题.


小智 5

依赖注入使您可以将对象的特定实现与其接口解耦。在大多数小例子中很难证明其合理性,但对于较大的系统来说,它可能是一个救星。它还可以帮助您在单元测试中隔离对象。

例如,如果您想为 CustomerService 类编写测试,您可以轻松注入 MockRepository 而不是 CustomerRepository。这将使您可以测试 CustomerService,而无需测试 CustomerRepository。

除了单元测试之外,我认为最容易可视化的示例可能是您正在为应用程序编写数据访问模块。您可能想要支持 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
Run Code Online (Sandbox Code Playgroud)

这还使您能够在将来添加对其他数据库的支持,从而将实现细节与应用程序的其余部分隔离。