Il Il gioco antipasto-plagato che sto creando utilizza ASP.NET Core, che, in molti casi, richiede l'uso dell'iniezione delle dipendenze. Questo è nuovo e contro-intuitivo per me. Fino ad ora, sono riuscito a limitare l'uso dell'iniezione di dipendenza al punto in cui è strettamente richiesto dal framework, mentre scrivevo la meccanica del gioco nel "mio" vecchio modo, cioè con molte creazioni di oggetti esplicite ( var blah = new SomeClass(arg1, arg2)
ecc.) (E senza creare interfacce solo quando una classe le implementerebbe.)
Leggendo un po 'sull'iniezione delle dipendenze, che la documentazione del framework raccomanda di utilizzare ovunque, sono rimasto perplesso nel constatare che non dovrei chiamare costruttori né creare oggetti esplicitamente, perché invece dovrei richiedere tutti gli oggetti che vorrei ClassA
per mai creare nel costruttore di ClassA
e lasciare che sia il framework a fornirmi per me!
Sfogliando il mio codice, in molti casi non riesco a vedere come potrei realizzare questo. Semplicemente spostando tutto new
s nel costruttore non sembra funzionare.
Un esempio è quando sembra essere dipendente dal tempo di esecuzione su quali oggetti devono essere creati.
Per essere più specifici, lascia che ti fornisca un esempio per questo esempio; P Ci sono molti% di caratteri che i% s di co_de possono usare:
public class Punch : Move
{
// ...
}
public class SwordSlash : Move
{
// ...
}
ecc.
Il client (browser) invierà di solito al server un comando con il nome della mossa che il giocatore vorrebbe eseguire. Omettendo le molte validazioni necessarie (per semplicità) questo è il codice del metodo rilevante del server:
var moveType = System.Type.GetType("Game.Mechanics."+moveTypeName);
if (!(moveType.BaseType == typeof(Move))) return; // OK one of the many validations I did not omit
move = (Move)Activator.CreateInstance(moveType, args);
Proprio così - il server guarda se c'è una classe il cui nome è equivalente alla stringa inviata dal client. Bene, violazione dell'iniezione di dipendenza?
Quindi come dovrei farlo invece?
L'unico modo che mi viene in mente è di avere una classe il cui contructor accetterà le mosse ALL (attualmente 79 e contando) e che avrà un metodo con un interruttore gigantesco per selezionare una mossa corretta:
public class MoveSelector : IMoveSelector
{
private readonly IPunch punch;
private readonly ISwordSlash swordSlash;
// 77 more privates
public MoveSelector (
IPunch punch,
ISwordSlash swordSlash,
// 77 more args
) {
this.punch = punch;
this.swordSlash = swordSlash;
// 77 more assignments
}
public IMove SelectMove(string moveName)
{
switch(moveName)
{
case "Punch":
return punch;
case "SwordSlash":
return swordSlash;
// 77 more cases
}
}
}
In qualche modo ritengo che questa non sia la strada giusta da percorrere. Tanto più che l'aggiunta di una nuova mossa sarebbe diventata piuttosto noiosa.
Quindi, come posso risolvere il mio codice in modo da non violare la regola che dovrei evitare la parola chiave Move
?