2 Stimmen

Die Behebung einer zyklischen Abhängigkeit mit einer Klasse, die Instanzen von sich selbst erstellen kann

Ich bin ganz neu in der Dependency Injection und habe mit Ninject herumgespielt, um kleine Testanwendungen zu erstellen, um die Konzepte zu verstehen. Mark Seemanns Dependency Injection in .NET steht als nächstes auf meiner Leseliste.

Ein Problem, dem ich bei meinen kurzen Tests begegnet bin, ist, dass ich nicht weiß, wie ich mit dem Fall umgehen soll, in dem eine Klasse eine neue Instanz ihres Typs instanziieren kann. Ein Beispiel wäre ein Formular mit einem Button. Wenn ein Benutzer auf den Button klickt, erstellt das Formular ein weiteres Formular vom gleichen Typ.

Wenn man keine DI verwendet, würden Sie in dem obigen Szenario einfach eine weitere Formular-Instanz im Click-Event-Handler des ursprünglichen Formulars erstellen. Meines Wissens (und ich kann in diesem Bereich naiv sein) wäre die bevorzugte Methode, eine abstrakte Fabrik zu verwenden, um Instanzen zu erstellen und von dieser Klasse abhängig zu machen.

Im Folgenden finden Sie den Code, den ich ausprobiert habe (nichts mit Formularen zu tun, nur einfache Klassen), der aufgrund zyklischer Abhängigkeiten nicht funktioniert, wobei ich sehe, warum dies auftritt. Mir fällt einfach keine gute Lösung ein, die nicht erfordert, dass ich manuell etwas neu erstelle. Ich habe das Gefühl, dass mir ein wichtiger Punkt fehlt.

public interface IMainClass
{
    IMainClass CreateNew();
    void Do();
}

public interface IMainClassFactory
{
    IMainClass CreateNew();
}

public class MainClassFactory : IMainClassFactory
{
    private readonly IMainClass _mainClass;

    public MainClassFactory(IMainClass mainClass)
    {
        _mainClass = mainClass;
    }

    public IMainClass CreateNew()
    {
        return _mainClass;
    }
}

public class MainClass : IMainClass
{
    private readonly IMainClassFactory _mainClassFactory;

    public MainClass(IMainClassFactory mainClassFactory)
    {
        _mainClassFactory = mainClassFactory;
    }

    public IMainClass CreateNew()
    {
        return _mainClassFactory.CreateNew();
    }

    public void Do()
    {
        Console.WriteLine("Do from Main Class");
    }
}

public class Program
{
    public static void Main()
    {
        IKernel kernel = new StandardKernel();

        kernel.Bind().To();
        kernel.Bind().To();

        var mainClassFactory = kernel.Get();
        var mainClass = mainClassFactory.CreateNew();

        mainClass.Do();

        Console.WriteLine("Drücken Sie die -Taste, um zu beenden...");
        Console.ReadLine();
    }
}

Ich weiß, dass dieser Code nicht korrekt ist.

  • Sollte IMainClass IMainClassFactory implementieren? Ist das wichtig?
  • kernel.Bind().To(); sieht nicht richtig aus, aber ich weiß nicht, was ich tun soll
  • Das Meisten Ihrer eigenen Objekte komplett zu instanziieren ist völlig verboten?
  • Ich glaube, ich habe ein ziemlich gutes Verständnis davon, den Service Locator Anti-Pattern nicht zu verwenden. Ich möchte nicht, dass meine Klassen sich der IOC-Container bewusst sind.

Ich bin sicher, dass solche Szenarien die ganze Zeit auftreten, daher suche ich nach der bevorzugten Lösung im Allgemeinen. Wenn möglich, möchte ich vermeiden, irgendwelche Ninject-spezifischen exotischen Features zu verwenden, falls ich zu einer anderen Implementierung wechseln möchte.

Bearbeiten 1: 'Autofac Circular Component Dependency Detected' Error Diese Frage scheint ähnlich zu sein, aber die akzeptierte Antwort scheint zu befürworten, einen Service Locator zu verwenden? Vielleicht lese ich das falsch, aber es scheint, als würde es das Hollywood-Prinzip verletzen

0voto

Steven Punkte 157957

Von reinem DI-Gesichtspunkt aus betrachtet, wäre eine abstrakte Fabrik der richtige Weg, aber vielleicht fehlt dir hier ein Muster:

Wenn ein Benutzer auf die Schaltfläche klickt, erstellt das Formular ein weiteres Formular des gleichen Typs.

Formulare sollten nicht direkt von anderen Formularen abhängen. Dies verdrahtet sie zusammen. Es sollte einen zentralen Punkt für die Behandlung der Bildschirmnavigation und des Flusses einer Anwendung geben. Mit anderen Worten, was Ihnen fehlt, ist ein Application Controller.

Ihr Formular sollte von einem IApplicationController oder etwas Ähnlichem abhängig sein. Dieser Anwendungscontroller könnte wiederum von einer abstrakten Fabrik abhängen, die neue Formulare erstellt.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X