Faccio largo uso di DI, ma mi chiedo, dov'è il limite di "granulosità", quando alcune serie di funzionalità dovrebbero essere separate in una classe - facciamo un esempio:
public class DownloadManager : IDownloadManager
{
public Uri ResourceIdentifier { get; }
public DownloadManager(Uri uniqueResourceIdentifier)
{
if (!uniqueResourceIdentifier.IsWellFormedOriginalString()) throw new ArgumentException(nameof(uniqueResourceIdentifier));
ResourceIdentifier = uniqueResourceIdentifier;
}
public DownloadManager(string uniqueResourceIdentifier) : this(new Uri(uniqueResourceIdentifier)) { }
public async Task<byte[]> GetBytesAsync(CancellationToken token = new CancellationToken())
{
using (var client = new HttpClient())
using (var response = await client.GetAsync(ResourceIdentifier, token).ConfigureAwait(false))
{
var data = await response.Content.ReadAsByteArrayAsync().ConfigureAwait(false);
return data;
}
}
}
Mi sembra che questa classe non porti quasi nessun ulteriore vantaggio, e persino ostacoli alcune operazioni:
- e se avessimo bisogno di uno stream (ReadAsStreamAsync ())?
- non è una grande idea sparpagliare il codice con async, poiché si diffonde come GPL (vedi anche Task etiqutte ).
- può condurre (ma in questo caso promuove piuttosto la composizione) al problema yo-yo
e potrebbe essere sostituito con un metodo statico come questo (o anche l'estensione alla classe Uri):
public static async Task<byte[]> GetBytesAsync(/*this */Uri uniqueResourceIdentifier, CancellationToken token = new CancellationToken())
{
if (!uniqueResourceIdentifier.IsWellFormedOriginalString()) throw new ArgumentException(nameof(uniqueResourceIdentifier));
using (var client = new HttpClient())
using (var response = await client.GetAsync(uniqueResourceIdentifier, token).ConfigureAwait(false))
{
var data = await response.Content.ReadAsByteArrayAsync().ConfigureAwait(false);
return data;
}
}
Ma non si può semplicemente DI un metodo statico, quindi questo sarà racchiuso nella classe sottile implementando un'interfaccia.
Opzione 3: La terza opzione sarebbe, il codice potrebbe essere scritto solo dove è necessario (l'API è grande, quasi nessuna configurazione ridondante), rischiando che, se necessario, il codice dovrà essere refactored (o copiato) nel futuro. Inoltre, potrebbe essere allettante piuttosto che creare una classe di Dio come FileManager, che scaricherà, decomprimerà CRUD & tutto, ma sacrificando la libertà e "S" da SOLID.
- Quale è il preferito in questo caso specifico (quasi lo stesso vale per decomprimere i file, usando ZipArchive e un paio di ottimi MS API)?
- In base a cosa, dovrei prendere una decisione su questo tre approcci da adottare?