【问题标题】:LightInject multiple constructorsLightInject 多个构造函数
【发布时间】:2016-11-04 17:07:48
【问题描述】:

使用 LightInject 已经有一段时间了,感觉很棒!但是,在尝试支持相同类型的多个构造函数时遇到了麻烦。请参阅下面的简化示例。 Foo 有四个构造函数,不同的是参数的类型和数量。我为每个构造函数注册一个映射。我第一次调用 GetInstance 来检索 IFoo 时,它因以下异常而崩溃。我错过了什么?我怎样才能完成这个功能?

InvalidCastException:无法将“LightInject.ServiceContainer”类型的对象转换为“System.Object[]”类型。

Public Interface IFoo

End Interface

Public Class Foo
    Implements  IFoo

    Public Sub New()

    End Sub

    Public Sub New(name As String)

    End Sub

    Public Sub New(age As Integer)

    End Sub

    Public Sub New(name As String, age As Integer)

    End Sub

End Class


container.Register(Of IFoo, Foo)
container.Register(Of String, IFoo)(Function(factory, name) New Foo(name))
container.Register(Of Integer, IFoo)(Function(factory, age) New Foo(age))
container.Register(Of String, Integer, IFoo)(Function(factory, name, age) New Foo(name, age))

Dim f1 As IFoo = container.GetInstance(Of IFoo)()                     'BOOM!
Dim f2 As IFoo = container.GetInstance(Of String, IFoo)("Scott")
Dim f3 As IFoo = container.GetInstance(Of Integer, IFoo)(25)
Dim f4 As IFoo = container.GetInstance(Of String, Integer, IFoo)("Scott", 25)

【问题讨论】:

  • 您的Foo 类看起来不像是应该由您的DI 容器解析的组件;它似乎是一个实体或 DTO。像这样的对象不应该由您的 DI 容器解析,因为这只会导致歧义。

标签: dependency-injection light-inject


【解决方案1】:

您可以使用 Typed Factories 干净利落地完成此操作。

http://www.lightinject.net/#typed-factories

Imports LightInject

Namespace Sample
    Class Program
        Private Shared Sub Main(args As String())
            Console.WriteLine("Go")

            Dim container = New ServiceContainer()
            container.Register(Of FooFactory)()

            Dim fooFactory = container.GetInstance(Of FooFactory)()
            Dim f1 As IFoo = fooFactory.Create()
            Dim f2 As IFoo = fooFactory.Create("Scott")
            Dim f3 As IFoo = fooFactory.Create(25)
            Dim f4 As IFoo = fooFactory.Create("Scott", 25)

            Console.WriteLine("Stop")
            Console.ReadLine()
        End Sub
    End Class

    Public Interface IFoo

    End Interface

    Public Class Foo
        Implements IFoo


        Public Sub New()
        End Sub


        Public Sub New(name As String)
        End Sub


        Public Sub New(age As Integer)
        End Sub


        Public Sub New(name As String, age As Integer)
        End Sub

    End Class

    Public Class FooFactory

        Public Function Create() As IFoo
            Return New Foo()
        End Function

        Public Function Create(name As String) As IFoo
            Return New Foo(name)
        End Function

        Public Function Create(age As Integer) As IFoo
            Return New Foo(age)
        End Function

        Public Function Create(name As String, age As Integer) As IFoo
            Return New Foo(name, age)
        End Function
    End Class
End Namespace

注意,如果您觉得 IFooFactory 接口增加了价值,您可以创建它。

【讨论】:

  • 感谢您的快速回答!需要使用工厂来实现这一点似乎是不必要的抽象层。我有一个包含一百多个实体的数据访问层,它们都实现了一个独特的接口。对工厂层的需求将导致需要数百个工厂和相应的接口定义。你知道吗,这样设计有技术原因吗?
  • 您的每个数据层类真的需要多个构造函数吗?它们是必要的(可能是因为类的行为会根据您使用的构造函数而变化),还是只是为了方便?如果是后者,我会坚持使用默认构造函数,因为它提供了使用 IOC 容器的最干净的路径,因为不需要工厂。
  • 我不得不问,为什么你需要一个 IOC 容器来更新你的数据层类?我见过过度使用依赖注入的代码库。你应该问自己,我在这里使用依赖注入是因为我需要模拟/伪造我正在注入的东西吗?如果答案是否定的,也许您不需要注入依赖项。在许多代码库中,数据层实际上只是一堆没有实际行为的结构,在这种情况下,我只是在需要它们的地方新建了那些数据层类。希望这会有所帮助。
  • 我们继承了一个代码库,它几乎是一个大型类库,包括 DAL、业务逻辑、辅助类等。我们一直在尝试将其分解为更小的、定义良好的、图书馆。不幸的是,有大量的循环引用,所以我们需要依赖注入来重构那个巨大的库。我们绝不会过度使用 DI。
  • 我们有多个构造函数,因为实例化实体有不同的用例。一种是创建一个空实体。另一种是提供主键 ID 并自动从数据库中填充。另一种是提供一个DataRow。我们还允许通过指定要作为参数加载到构造函数的属性来部分填充实体。
猜你喜欢
  • 2018-09-16
  • 1970-01-01
  • 1970-01-01
  • 2012-05-09
  • 1970-01-01
  • 2022-10-17
  • 1970-01-01
  • 2011-11-20
  • 2011-07-06
相关资源
最近更新 更多