2017-12-01 6 views
1

ich einen Algorithmus haben zu laufen, wie folgt aus:ninject komplexe Injektion mit dynamischen Daten

public interface IAlgorithm 
{ 
    void Run(); 
} 

Es ist auf der IContainer Schnittstelle abhängt, die wie folgt aussieht:

public interface IContainer 
{ 
    int Size(); 
} 

Die UMSETZUNG dieser Schnittstelle Bedürfnisse einige von der UI erhaltene Daten

public class Container : IContainer 
{ 
    private readonly List<int> _data; 

    public Container(IEnumerable<int> data) 
    { 
     _data = new List<int>(data); 
    } 

    public int Size() 
    { 
     return _data.Count; 
    } 
} 

Dann könnte die Implementierung von IAlgorithm l aussehen diese ike:

public class Algorithm : IAlgorithm 
{ 
    private readonly IContainer _container; 

    public Algorithm(IContainer container) 
    { 
     _container = container; 
    } 

    public void Run() 
    { 
     Console.WriteLine(_container.Size()); 
    } 
} 

ich diese Schnittstelle implementieren möge, so dass es über ninject injectible ist (so kann ich es als Konstrukteur Parameter für ein Ansichtsmodell verwenden).

public interface IAlgorithmFactory 
{ 
    IAlgorithm Create(IEnumerable<int> data); 
} 

Das Problem ist: Ich brauche die richtige Instanz von IContainer vom Kernel während der Algorithm Konstruktion erhalten zu können. In den realen Situationen ist das Abhängigkeitsdiagramm des Algorithmus ziemlich groß und es gibt nicht eine Sache, die aus den Daten erstellt werden muss, sondern 3 und diese Dinge sind weitere Abhängigkeiten von anderen Dingen.

Meine Lösung ist, dass alle Klassen, die aus den Daten erstellt werden müssen, die Methode Initialize haben. Der Aufrufer muss diese Server initialisieren, bevor er andere Methoden verwendet. Das klingt nach einer schlechten Übung.

In der Tat kann der echte Code, über den ich rede, here gesehen werden. Im Moment wird alles als Singleton injiziert.

Gibt es eine andere Möglichkeit, diese Dinge über NInject zu injizieren?

Hinweis: Ich habe diese Frage here bereits von einem Design-Standpunkt aus gestellt. Ich denke, dies ist der bessere Ort, um die Antwort speziell zu einer NInject-Lösung zu erhalten.

Antwort

1

Nur durch Ninject Konfiguration verwenden, können Sie es auf diese Weise tun:

 var kernel = new StandardKernel(); 
     kernel.Bind<IContainer>() 
      .To<Container>() 
      .WithConstructorArgument("data", 
       ctx => ctx.Request.ParentContext.Parameters 
        .Single(x => x.Name == "data") 
        .GetValue(ctx, null)); 
     kernel.Bind<IAlgorithm>().To<Algorithm>(); 
     kernel.Bind<IAlgorithmFactory>().ToFactory(); 

     var factory = kernel.Get<IAlgorithmFactory>(); 
     var algorithm = factory.Create(new List<int>() { 1 }); 

Hier ist die data Parmeter von der Factory-Methode Parameter genommen und weitergegeben an den Container Konstruktor.