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