dependency-injectionlight-inject

LightInject multiple constructors


Been using LightInject for a while now and it has been great! Hit a snag trying to support multiple constructors of the same type, though. See the simplified example below. Foo has four constructors, differing by the type and number of arguments. I register one mapping per constructor. The first time I call GetInstance to retrieve an IFoo, it blows up with the following exception. What am I missing? How can I accomplish this functionality?

InvalidCastException: Unable to cast object of type 'LightInject.ServiceContainer' to type '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)

Solution

  • You can use Typed Factories to cleanly accomplish this.

    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
    

    Note, you can create an IFooFactory interface if you feel it adds value.