【问题标题】:Creating runtime objects with Unity Container使用 Unity Container 创建运行时对象
【发布时间】:2016-06-30 10:33:11
【问题描述】:

我有一个现有的 winforms 应用程序,我正在尝试重新设计以现在将 Unity 用作容器,而不必手动在各处创建对象。目前情况还不错,但我们将扩展程序,如果没有 Unity,我会看到事情变得复杂。我正在努力了解如何创建一些依赖于运行时信息的对象。 以下面的代码为例说明当前的工作方式(该程序允许您一次查看多个客户,每个客户都在一个新标签上)........

Public Class CustomerSearchPresenter
    Implements ICustomerSearchPresenter

    Private Repo As ICustomerRepo
    Private View As ICustomerSearchView

    Public Sub New(_view As ICustomerSearchView, _customerRepo As ICustomerRepo)
        View = _view
        Repo = _customerRepo
    End Sub

    Public Sub SearchForCustomer(_customerNumber As String) Implements ICustomerSearchPresenter.SearchForCustomer
        'seach the database to see if customer exists and if so create a new customer view...
        Dim foundCustomer As ICustomer = Repo.find(_customerNumber)
        If Not IsNothing(foundCustomer) Then
            '* Manual creation of all objects happens here - how do I change this in unity to create a new 
            Dim cusView As New customerView
            Dim custPresenter As New CustomerPresenter(cusView, foundCustomer)
            'custPresenter creates a new tab on the main form to display the details for that customer
        Else
            View.feedback("No customer found for " & _customerNumber)
        End If

    End Sub

End Class

Public Class CustomerPresenter
    Implements ICustomerPresenter

    Private View As ICustomerView
    Private Customer As ICustomer

    Public Sub New(_View As ICustomerView, _customer As ICustomer)
        View = _View
        Customer = _customer
    End Sub

    Public Sub RefreshData() Implements ICustomerPresenter.RefreshData
        'do some stuff here ....
    End Sub

End Class

每次用户搜索有效的客户编号时,CustomerSearchPresenter 负责创建一个新的客户部分。这很简单,因为客户对象由存储库返回,我们可以在创建相关视图/演示者时手动注入它(尽管这是基于 MVP,但我猜同样的理论适用于 MVC 等)。

我第一次尝试使用 Unity 重新处理它(使用 Func(of))但它不起作用 - 调用调用不会为我创建一个新对象并返回相同的对象。每次用户搜索时,我应该如何创建一个新的客户特定演示者?

Public Class CustomerSearchPresenter
    Implements ICustomerSearchPresenter

    Private Repo As ICustomerRepo
    Private View As ICustomerSearchView
    Private Builder As Func(Of ICustomerPresenter)

    Public Sub New(_view As ICustomerSearchView, _customerRepo As ICustomerRepo, _customerBuilder As Func(Of ICustomerPresenter))
        View = _view
        Repo = _customerRepo
    End Sub

    Public Sub SearchForCustomer(_customerNumber As String) Implements ICustomerSearchPresenter.SearchForCustomer
        'seach the database to see if customer exists and if so create a new customer view...
        Dim foundCustomer As ICustomer = Repo.find(_customerNumber)
        If Not IsNothing(foundCustomer) Then
            '* Assumed I could call invoke and then register the customer afterwards, but this just invokes the same object
            Dim custPresenter As ICustomerPresenter = Builder.Invoke
            custPresenter.registerCustomer(_foundCustomer)
        Else
            View.feedback("No customer found for " & _customerNumber)
        End If

    End Sub

End Class

编辑:func(of) 方法确实有效,我使用 ContainerControlledLifetimeManager 注册了该类型,这意味着它总是返回相同的 Presenter。那么现在可行,这是解决它的最佳/正确方法吗?

编辑 2:感谢向我指出其他问题,但我正在努力将它们应用到我的代码中。我仍然需要从容器中解析我的对象(不传递容器),这意味着以下示例如何帮助我解决这个问题...

Public Class CustomerPresenterFactory
    Implements ICustomerPresenterFactory

    Function Create(_customer As ICustomer) As ICustomerPresenter Implements ICustomerPresenterFactory.Create
        Return ????
    End Function

End Class

除了视图等客户之外,我无法访问演示者需要的任何对象。

【问题讨论】:

标签: .net vb.net inversion-of-control unity-container ioc-container


【解决方案1】:

我采用了以下解决方案,我认为它可以全面解决问题。我现在可以创建一个客户演示者并且知道它会被赋予一个客户对象来使用。

Public Class CustomerPresenterFactory
        Implements ICustomerPresenterFactory

        Private creator As Func(Of ICustomerPresenter)

        Public Sub New(_creator As Func(Of ICustomerPresenter))
            creator = _creator
        End Sub

        Function Create(_customer As ICustomer) As ICustomerPresenter Implements ICustomerPresenterFactory.Create
            Dim obj As ICustomerPresenter = creator.Invoke
            obj.Customer = _customer
            Return obj
        End Function

    End Class

原帖中的 searchPresenter 现在将此作为依赖项,并且可以在每个成功的搜索结果后创建一个新的 CustomerPresenter。

我慢慢地开始看到我在如何进行依赖注入方面的一些错误/学习。我不知道这是否是正确的解决方案,但根据我目前的理解,这感觉是比原始代码更好的解决方案。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-03-09
    • 1970-01-01
    • 1970-01-01
    • 2011-06-11
    相关资源
    最近更新 更多