0

Ich habe eine Winforms-Anwendung, die ich versuche zu überarbeiten, jetzt Unity als Container zu verwenden, anstatt manuell Objekte überall zu erstellen. Im Moment sind die Dinge nicht so schlecht, aber wir werden das Programm erweitern und ohne Unity sehe ich, dass es kompliziert wird. Ich habe Mühe zu verstehen, wie man einige Objekte erstellt, die von Laufzeit-Informationen abhängen. Nehmen Sie den folgenden Code als ein Beispiel dafür, wie die Dinge zur Zeit arbeiten (das Programm ermöglicht es Ihnen, auf einmal mehrere Kunden zu betrachten, von denen jeder auf einem neuen Tab) ... ..Erstellen von Laufzeitobjekten mit Unity Container

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 

Die CustomerSearchPresenter verantwortlich ist, eine neue für die Erstellung von Kundenbereich jedes Mal, wenn der Benutzer eine gültige Kundennummer sucht. Dies ist einfach genug, da das Kundenobjekt vom Repository zurückgegeben wird und wir es beim Erstellen der zugehörigen Ansicht/des Präsentators manuell einfügen können (obwohl dies auf MVP basiert, vermute ich, dass die gleiche Theorie für MVC usw. gilt).

Mein erster Versuch, dies mit Unity zu überarbeiten, war der folgende (mit Func (of)), aber es funktioniert nicht - der Aufruf Aufruf erstellt mir kein neues Objekt und gibt das gleiche zurück. Wie sollte ich jedes Mal einen neuen kundenspezifischen Moderator erstellen, wenn der Benutzer nach einem solchen sucht?

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 

Edit: Die func (von) Methode funktioniert, habe ich die Art registriert mit ContainerControlledLifetimeManager was bedeutet, es immer den gleichen Presenter zurückgegeben. Also, das ist jetzt der beste/richtige Weg, um es zu lösen?

Edit 2: Danke, mich auf die anderen Fragen zu zeigen, aber ich habe Mühe, sie auf meinen Code anzuwenden. Ich muss noch meine Objekte aus dem Behälter gelöst werden (ohne den Behälter herumgereicht) was bedeutet, wie funktioniert das folgende Beispiel helfen mir, dass zu lösen ...

Public Class CustomerPresenterFactory 
    Implements ICustomerPresenterFactory 

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

End Class 

Ich würde keinen Zugriff auf Objekte der Moderator braucht neben dem Kunden auch den View.

+0

Mögliches Duplikat von [Gibt es ein Muster zum Initialisieren von Objekten, die über einen DI-Container erstellt wurden] (http://stackoverflow.com/questions/1943576/is-there-a-pattern-for-initializing-objects-created-via -a-di-container) – NightOwl888

+0

Zugehörig: [Dependency-Injection-Anti-Pattern: Laufzeitdaten in Komponenten einfügen] (https://cuttingedge.it/blogs/steven/pivot/entry.php?id=99) – NightOwl888

Antwort

0

Ich bin mit der folgenden Lösung gegangen, die ich denke, löst das Problem in einer Runde über. Ich kann jetzt einen Kundenpräsentator erstellen und weiß, dass ihm ein Kundenobjekt zugewiesen wird.

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 

Die searchPresenter in der ursprünglichen Nachricht nimmt nun diese als Abhängigkeit und können einen neuen CustomerPresenter nach jedem erfolgreichen Suchergebnis erstellen.

Ich beginne langsam zu sehen, einige meiner Fehler/lernt mit der Abhängigkeit Injektion zu tun. Ich weiß nicht, ob das die richtige Lösung ist, aber mit meinem derzeitigen Verständnis fühlt sich das eine viel bessere Lösung als der ursprüngliche Code an.