[c#] Die Verwendung des DI-Containers im Kompositionswurzel in Silverlight und MVVM beibehalten



Answers

Question

Es ist mir nicht ganz klar, wie ich das gestalten kann, daher behalte ich den Verweis auf den DI-Container im Kompositionswurzel für eine Silverlight + MVVM-Anwendung.

Ich habe das folgende einfache Anwendungsszenario: Es gibt eine Hauptansicht (möglicherweise eine Liste von Elementen) und eine Aktion zum Öffnen einer Bearbeitungsansicht für ein einzelnes Element. Daher muss die Hauptansicht die Bearbeitungsansicht erstellen und anzeigen, wenn der Benutzer die Aktion ausführt (z. B. auf eine Schaltfläche klickt).

Dafür habe ich folgenden Code:

public interface IView
{
   IViewModel ViewModel {get; set;}
}

Dann muss ich für jede Ansicht, die ich erstellen kann, eine abstrakte Fabrik haben

public interface ISomeViewFactory
{
   IView CreateView();
}

Diese Factory wird dann wie folgt als Abhängigkeit des "Parent" View-Modells deklariert:

public class SomeParentViewModel
{
   public SomeParentViewModel(ISomeViewFactory viewFactory)
   {
       // store it
   }

   private void OnSomeUserAction()
   {
      IView view = viewFactory.CreateView();
      dialogService.ShowDialog(view);
   }       
} 

Also alles ist gut bis hier, kein DI-Container in Sicht :). Jetzt kommt die Implementierung von ISomeViewFactory:

public class SomeViewFactory : ISomeViewFactory
{
    public IView CreateView()
    {
        IView view = new SomeView();
        view.ViewModel = ????   
    }
}

Das "????" Teil ist mein Problem, weil das Ansichtsmodell für die Ansicht aus dem DI-Container aufgelöst werden muss, damit es seine Abhängigkeiten einfügt. Was ich nicht weiß, ist, wie ich das tun kann, ohne eine Abhängigkeit von dem DI-Container irgendwo außer dem Kompositionswurzel zu haben.

Eine mögliche Lösung wäre, eine Abhängigkeit vom Ansichtsmodell zu haben, das in die Fabrik injiziert wird:

public class SomeViewFactory : ISomeViewFactory
{
    public SomeViewFactory(ISomeViewModel viewModel)
    { 
       // store it
    }

    public IView CreateView()
    {
        IView view = new SomeView();
        view.ViewModel = viewModel;
    }
}

Während dies funktioniert, besteht das Problem, dass das gesamte Objektdiagramm "statisch" verdrahtet ist (dh das "übergeordnete" Ansichtsmodell erhält eine Instanz von SomeViewFactory, die eine Instanz von SomeViewModel erhält, und diese wird so lange leben wie Das "Eltern" -Ansichtmodell lebt), die Implementierung des Modells des injizierten Views ist statusbehaftet und wenn der Benutzer die Child View zweimal öffnet, ist das View Model das zweite Mal die gleiche Instanz und hat den Status von vorher. Ich denke, ich könnte das mit einer "Initialize" -Methode oder etwas Ähnlichem umgehen, aber es riecht nicht ganz richtig.

Eine andere Lösung wäre, den DI-Container einzupacken und die Fabriken vom Wrapper abhängig zu machen, aber es wäre immer noch ein "verkleideter" DI-Container :)

ps: Meine derzeitige Lösung ist, dass die Fabriken über den DI-Container Bescheid wissen, und nur diese und der Composition Root diese Abhängigkeit haben.




Links