Posso usare Dependency Injection per testare la mia classe quando è necessario un costruttore senza parametri?

0

Desidero utilizzare PowerArgs per un'applicazione console che sto scrivendo. Offre alcune caratteristiche interessanti che mi piacerebbe provare. La mia radice ha questo aspetto:

public static void Main(string[] args)
    {
        try
        {
            Args.InvokeAction<MyClass>(args);
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.Message);
        }
        Console.ReadKey();
    }

Piuttosto interessante: PowerArgs crea un'istanza di MyClass , analizza il dato args e chiama l'azione corrispondente, definita dagli attributi come segue:

public class MyClass
{
    private readonly IConsole _console;
    private readonly IOtherDependency _dep;

    public Summoner(IConsole console, IOtherDependency dep)
    {
        _console = console;
        _dep = dep;
    }

    [ArgActionMethod]
    public void DoMyThing(
        [StickyArg][ArgRequired] string name,
        [StickyArg][ArgRequired] string street,
        [ArgRequired] string favoriteMeal)
    {
        var stuff = _dep.GetStuff(street, name);

        var properties = stuff.GetType().GetProperties();
        foreach (var property in properties)
        {
            _console.Write($"{property.Name}:{property.GetValue(summoner)}");
        }
    }
}

}

Potresti aver già visto il mio problema. PowerArgs genera un'eccezione poiché non può creare un'istanza di MyClass . Dice che ha bisogno di un costruttore parametrico per farlo. Ma non voglio creare una console hard-coded nella mia classe o fare qualcosa come _dep = new OtherDependency() nel mio metodo poiché non sarei in grado di testare l'unità. C'è un modo per usare l'integrazione delle dipendenze con un costruttore senza parametri?

Grazie in anticipo!

    
posta selmaohneh 28.06.2018 - 14:48
fonte

1 risposta

1

Se c'è una discrepanza tra l'interfaccia che vuoi e l'interfaccia che un altro sistema si aspetta, considera l'uso di un qualche tipo di adattatore o indiretto. Ciò limita l'utilità del framework che stai utilizzando, ma ti offre una maggiore flessibilità.

In questo caso, la funzione di destinazione potrebbe semplicemente costruire una struttura in stile DTO che mantiene solo i parametri. Successivamente, è possibile eseguire il codice effettivo. L'utilizzo sarebbe qualcosa di simile:

var parsedArgs = Args.InvokeAction<ParsedArgs>(args);
runActualCode(dependencies, parsedArgs);

dove

class ParsedArgs {
  public string Name { get; };
  public string Street { get; };
  public string FavoriteMeal { get; };

  [ArgActionMethod]
  public void DoMyThing(
    [StickyArg][ArgRequired] string name,
    [StickyArg][ArgRequired] string street,
    [ArgRequired] string favoriteMeal)
  {
    Name = name;
    Street = street;
    FavoriteMeal = favoriteMeal;
  }
}

In questo caso particolare , la libreria in questione supporta già metodi alternativi per specificare argomenti oltre a questo approccio InvokeAction/ArgActionMethood . Potresti trovarli più facili quando costruisci un oggetto che rappresenta gli argomenti analizzati.

Se la libreria è stata sviluppata per la massima flessibilità, non farebbe alcuna ipotesi sul ciclo di vita dell'oggetto azione ma ti permetterà di passare in un oggetto già costruito, ad es.

Args.InvokeAction(new MyClass(dependencies), args);

Forse un tale metodo è già implementato in quella libreria?

    
risposta data 28.06.2018 - 15:44
fonte

Leggi altre domande sui tag