2016-07-10 2 views
3

Etwas wie ein String-Parameter in einem Konstruktor macht Dependency-Injektion sehr unordentlich. Denken Sie:Dependency Injection in Akka .NET mit State-Constructor-Parametern

public class CurrencyActor 
{ 
    public CurrencyActor(string currency, IRepository repository) 
    { 
... 

Es wurden andere Fragen (wie this one) dieses besondere Problem mit Dependency Injection zu adressieren. Dies wird oft dadurch gelöst, dass Design und Refactoring überdacht werden.

Was aber, wenn es tatsächlich sinnvoll ist, mehrere Versionen eines Objekts zu haben, die jeweils für unterschiedliche Daten verantwortlich sind (z. B. ein CurrencyActor für jede Währung)? Dies ist bei Verwendung eines Aktormodells wie Akka .NET ziemlich normal, macht aber auch außerhalb dieser Domäne Sinn.

Was ist der beste Weg, um diese mehreren Instanzen mit Abhängigkeitsinjektion zu erstellen, während sie den Anfangszustand übergeben, den sie benötigen?

Antwort

6

Eine Abhängigkeit in einem Konstruktor ist nicht unordentlich, es ist sehr sehr häufig. Daran ist nichts falsch.

Sie können eine Standard-Requisiten statische Methode auf dem CurrencyActor erstellen, die in Ihren Abhängigkeiten nimmt:

public static Props CreateProps(string currency, Irepository repo) 
    { 
     return Props.Create(() => new CurrrncyActor(currency, repo)); 
    } 

dann so viele erstellen, wie Sie möchten:

var usCurrency = system.ActorOf(CurrencyActor.CreateProps("US", someRepo), "US"); 
var swedishCurrency = system.ActorOf(CurrencyActor.CreateProps("SEK", someRepo), "SEK"); 

[Update]

Bezüglich der Verwendung von DI-Containern mit Akka wurde diese als Nr. 2 aus den Top 7 Fehler machen Menschen, wenn akka.net mit

https://petabridge.com/blog/top-7-akkadotnet-stumbling-blocks/

So eine gute Praxis gilt es als sein für die Akteure ihre eigenen Abhängigkeiten zu verwalten, anstatt Delegierten, die zu einem DI Rahmen arbeiten .

Also im Grunde tun Sie es nicht. Und wenn müssen Sie nach diesem Artikel ist Autofac die beste Wahl

[Update 2]

Wenn Sie möchten, dynamisch neue Instanzen des gleichen Schauspieler erstellen, aber einige Anfangszustand ändern, dann Sie haben könnten Betreuer, die für die Erstellung von ihnen verantwortlich ist:

public class MatchesSupervisor : ReceiveActor 
{ 
    List<IActorRef> _matches = new List<IActorRef>(); 
    public void MatchesSupervisor() 
    { 
     Receive<SomeCommandToStartANewMatch>(msg => 
     { 
      // store the currently active matches somewhere, maybe on a FullTime message they would get removed? 
      _matches.Add(Context.ActorOf(MatchActor.Create(msg.SomeMatchId))); 
     } 
    } 
} 

im obigen Beispiel gibt es keine DI-Container verwendet wird, und wenn jeder MatchActor da noch etwas anderes, wie ein IRepository, würde dann diese in die MatchesSupervisor übergeben werden, wenn es wird erstellt und anschließend bei der Erstellung an jeden MatchActor übergeben.

Es hängt auch davon ab, wo der Zustand herkommt, und was der Mechanismus ist, um ein neues Spiel zu starten - ich habe gerade angenommen, dass ein anderer Akteur eine Nachricht sendet.

(Ich tippe auf ein iPad, damit der obige Code nicht wirklich kompiliert, aber hoffentlich bekommst du die Idee, ich habe auch eine Implementierung von MatchActor weggelassen, aber es wäre nur ein Actor, der einige Werte in seine übergeben bekommt Konstruktor)

Hoffe, das hilft!

+0

Aber dieser Ansatz verwendet das DI-Framework überhaupt nicht ... – Gigi

+0

@Gigi Was DI-Framework? Warum brauchen Sie ein DI-Framework? Sie können Dependency-Injection ohne ein Framework tun, und es ist oft viel einfacher – tomliversidge

+0

Die Frage fragt nach DI in Akka .NET. Dies beinhaltet die Verwendung eines Rahmens. – Gigi