在Ninject中使用构造函数参数提供ToProvider不会绑定正确的构造函数

时间:2014-06-19 15:33:44

标签: .net vb.net inversion-of-control ninject

我有这个简单的绑定:

Bind(Of ISessionFactory).ToProvider(Of SessionProvider) _
             .InSingletonScope() _
             .WithConstructorArguments("connectionString ", "test")

使用此提供商:

Public Class SessionProvider
    Inherits Provider(Of ISessionFactory)

    Private ReadOnly ConnectionString As String

    Public Sub New(connectionString as String)
        Me.ConnectionString = connectionString
    End Sub

    Protected Overrides Function CreateInstance(context As IContext) As ISessionFactory
        Return New SessionFactory(connectionName)
    End Function
End Class

但是当它解决工厂时总是调用没有参数的默认构造函数。我尝试将Inject属性添加到构造函数中,我甚至尝试添加一个私有的默认构造函数。什么都行不通。

到目前为止,我唯一的解决方案是创建另一个自动解决的类。它看起来像这样:

我的中间工厂有构造函数参数:

Public Class MySessionFactory
    Private ReadOnly ConnectionName As String

    Private Factory As ISessionFactory

    Public Sub New(ByVal connectionName As String)
        Me.ConnectionName = connectionName
    End Sub


    Public Function GetFactory() As ISessionFactory
        Return new SessionFactory(ConnectionName)
    End Function
End Class

提供者:

Public Class SessionProvider
    Inherits Provider(Of ISessionFactory)

    Private ReadOnly FactoryProvider As SessionFactory

    Public Sub New(factory As MySessionFactory)
        Me.FactoryProvider = factory
    End Sub

    Protected Overrides Function CreateInstance(context As IContext) As ISessionFactory
        Return FactoryProvider.GetFactory()
    End Function
End Class

我的绑定采用构造函数args:

Bind(Of SessionFactory).ToSelf().WithConstructorArgument("connectionName", "TEST")
Bind(Of ISessionFactory).ToProvider(Of SessionProvider).InSingletonScope()

这个中间类将与构造函数参数绑定,但它不是一个真正的解决方案,因为它不会解耦任何东西。如果我这样做的话,我不妨将连接名称硬编码到提供者中......这显然不好......

所以我想避免这个中间类,并希望我的提供者接受构造函数参数?

2 个答案:

答案 0 :(得分:1)

你试过了吗?

Bind(Of ISessionFactory).ToProvider(Of SessionProvider) _
         .InSingletonScope()

Bind(Of SessionProvider).ToSelf() _
         .WithConstructorArguments("connectionString ", "test")

作为解决方法?

另请注意,.InSingletonScope()会影响ISessionFactory,而不会影响SessionProvider。 你告诉ninject不要实现多个ISessionFactory。当然,不会超过一个SessionProvider - 在创建第一个且仅ISessionFactory个实例后,不需要创建更多它们。

但是,如果您只想创建一个SessionProvider而只需创建多个ISessionFactory,则还必须为SessionProvider创建绑定并将其设置为.InSingletonScope() - 就像我上面用.WithConstructorArguments(...)显示的那样。

答案 1 :(得分:1)

您的绑定定义

Bind(Of ISessionFactory).ToProvider(Of SessionProvider) _
         .InSingletonScope() _
         .WithConstructorArguments("connectionString ", "test")

ISessionFactory绑定到类型为SessionProvider的提供商。构造函数参数仅用于解析类型ISessionFactory的请求,而不是用于解析SessionProvider的请求。在您的示例中,Ninject最初创建了SessionProvider的请求。因此,您必须为SessionProvider定义一个额外的绑定,如上一篇文章所述。

请求ISessionFactory时,构造函数参数将传递给请求。检查CreateInstance覆盖中的上下文参数的参数(c#代码,我不熟悉VB.NET)

    protected override Service CreateInstance(IContext context)
    {
        string t = (string)context.Parameters.Cast<IConstructorArgument>().First().GetValue(context, context.Request.Target);
        return new Service(t);
    }