【问题标题】:Ninject with Windows ApplicationNinject 与 Windows 应用程序
【发布时间】:2011-03-29 22:20:55
【问题描述】:

我想在我的 Windows 应用程序中使用 Ninject,我想知道是否有我可以做的最佳实践;在性能和维护之间找到平衡的策略。

Windows 应用程序和 Web 应用程序的问题在于,在 Web 应用程序中,有一个易于定义的范围,即上下文,但在 Windows 应用程序中,您没有一个又一个表格易于使用的范围。

例如,我有一个查询数据库的服务。该服务有一个构造函数并收到一个 UnitOfWork。使用 Ninject,我可以创建一个标记为要注入的属性,但如果这样做,每次创建此服务时,都会创建一个到数据库的新连接。

正因为如此,我必须手动创建我的服务来控制创建的连接数,并且不能使用依赖注入器。

我发现您可以在为注入依赖项创建服务后调用 Inject 方法,但我确信我可以使用更好的策略。

【问题讨论】:

    标签: dependency-injection database-connection desktop-application ninject architecture


    【解决方案1】:

    使用 Ninject,您可以将注入依赖项的 Ninject 作用域生命周期设置为您想要提供的任何对象(不仅仅是单例、请求、线程和瞬态作用域)。

    来自Ninject Documentation Wiki

    您还可以轻松定义自己的 使用 .InScope(object o) 的范围 方法。

    您将在 this Ninject Google Groups question & answer 中找到有关对象范围如何工作的一些实际细节。

    【讨论】:

    • +1 和相关链接 kohari.org/2009/03/06/… 是理解 Ninject 2.0 范围的必读内容
    • 阅读了链接的文章后,我现在更好地理解了如何控制注入的依赖对象的生命周期。这很好,但如果没有出色的架构,维护起来可能会很尴尬。似乎很少有人在网上给出关于如何设计一个好的 Windows 应用程序以及如何在 winform 中启动对象范围的技巧,同时记住许多其他表单可以一起工作。我使用 Mindscape 的 LightSpeed 和 UnitOfWork 使用缓存,当您有许多一起工作的 winform 时,必须经常共享数据。任何机构都有具体的项目样本?
    • @Samuel,老实说,我没有看到太多具体的示例应用程序,这些示例应用程序展示了带有 ORM 和 UnitOfWork 的 Windows 窗体在整个架构良好的应用程序中使用。如果我能找到的话,我当然想亲自去看看。
    • 非常感谢您的回答。我将搜索具有这些规范的示例项目并将其发送到此处。
    【解决方案2】:

    我终于找到了我要寻找的东西。

    创建一个继承自 'Ninject.Activation.Provider(of T)' 的类

    覆盖函数“CreateInstance”

    用'Bind(Of [Your interface]).ToProvider([Your provider class])'绑定你的接口

    现在,您将能够控制创建的与指定接口相关联的每个实例。

    请注意,您可以将类型或实例传递给 Bind 方法的 provider 参数。您可以在绑定接口之前使用实例创建提供程序,并在您想要创建新实例时在代码中使用此提供程序。

    提供程序与 InScope 结合使用可为您想要拥有的每个位置以及可以自动注入并具有确定范围的对象实例提供极大的灵活性。

    这是一个例子:

    Public Interface IConnection
    
    End Interface
    
    Public Class Connection
       Implements IConnection
    
    End Class
    
    Imports Ninject
    
    Public Class StandardModule
       Inherits Ninject.Modules.NinjectModule
    
       Public Property ConnectionProvider As ConnectionProvider
    
       Public Overrides Sub Load()
          Bind(Of IConnection).ToProvider(Me.ConnectionProvider)
       End Sub
    End Class
    
    Public Class ConnectionProvider
       Inherits Ninject.Activation.Provider(Of IConnection)
    
       Public Property Connection As IConnection
    
       Protected Overrides Function CreateInstance(ByVal context As Ninject.Activation.IContext) As IConnection
          Return Me.Connection
       End Function
    End Class
    
    Imports Ninject
    
    Module EntryPoint
       Sub Main()
          Dim provider As New ConnectionProvider
          Dim standardModule As New StandardModule
          Dim connection As IConnection
          Dim kernel As New Ninject.StandardKernel()
    
          standardModule.ConnectionProvider = provider
    
          kernel = New Ninject.StandardKernel(standardModule)
    
          ' Here you should use a factory instead of create an instance directly but
          ' for demonstration, it show how an instance can be propagated to object created
          ' by NInject.
          provider.Connection = New Connection
    
          connection = kernel.Get(Of IConnection)()
       End Sub
    End Module
    

    【讨论】:

    • 很高兴听到你觉得你有答案了。只要您有完整的 lambda 方法(在 VB 中不完整,直到 Ver X(2010 年?),通常使用 Bind.ToMethod() - 如果您实际上有足够复杂的东西需要一个类,通常您应该将其作为一个容器来执行- 不可知的东西作为你的域逻辑的一部分。但它肯定有一个地方好吧,尤其是如果你没有适当的 lambdas。
    【解决方案3】:

    This article by Ayende in MSDN Magazine 表面上是关于 NHibernate,并且只提到过一次注入这个词(而且只提到 AOP),但是你的问题的措辞向我表明,当你考虑如何构建你的应用程序。

    【讨论】:

      【解决方案4】:

      您还可以让您的框架依赖于工厂实例,并依赖工厂来执行连接池。

      或者,您可以使用 Ninject 本身来始终为特定类型使用相同的对象实例。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-12-02
        • 2014-06-26
        • 1970-01-01
        • 2012-05-25
        • 2012-01-04
        • 1970-01-01
        相关资源
        最近更新 更多