Immagine evocativa sulla libertà che i generics ci danno

Generics c# un caso d’uso

In questo articolo vedremo un caso d’uso sull’utilizzo dei generics. In generale lo sviluppo di librerie condivise sui progetti è l’ambito più utilizzato per i Generics in C#.

Supponiamo di voler creare una libreria generica che collega le nostre API aziendali a Shopify.

Leggi tutto: Generics c# un caso d’uso

L’obiettivo è creare una libreria che:

  • Consenta di connettersi all’API di Shopify.
  • Fornisca metodi tipizzati per interagire con entità come i prodotti.
  • Usi i generics per ridurre il codice ripetitivo e migliorare la flessibilità.

Iniziamo creando una classe generica che rappresenti un’entità Shopify. Tutte le entità in Shopify hanno degli attributi comuni come Id, CreatedAt, UpdatedAt.

public abstract class ShopifyEntity
{
    public string Id { get; set; }
    public DateTime CreatedAt { get; set; }
    public DateTime UpdatedAt { get; set; }
}

// Modello specifico per i prodotti Shopify
public class ShopifyProduct : ShopifyEntity
{
    public string Title { get; set; }
    public string Vendor { get; set; }
    public decimal Price { get; set; }
    public int Stock { get; set; }
}

Adesso creiamo una classe generica ShopifyClient<T> che gestisce le richieste API per una qualsiasi entità Shopify.

public class ShopifyClient<T> where T : ShopifyEntity
{
    private readonly HttpClient _httpClient;
    private readonly string _shopifyUrl;
    private readonly string _accessToken;

    public ShopifyClient(string shopifyUrl, string accessToken)
    {
        _httpClient = new HttpClient();
        _shopifyUrl = shopifyUrl;
        _accessToken = accessToken;
    }

    private async Task<string> GetEndpointAsync()
    {
        // Ottieni il nome della risorsa in base al tipo T
        if (typeof(T) == typeof(ShopifyProduct))
            return "products";
        throw new NotSupportedException($"Type {typeof(T).Name} not supported.");
    }

    public async Task<IEnumerable<T>> GetAllAsync()
    {
        var endpoint = await GetEndpointAsync();
        var requestUrl = $"{_shopifyUrl}/admin/api/2024-01/{endpoint}.json";

        using var request = new HttpRequestMessage(HttpMethod.Get, requestUrl);
        request.Headers.Add("X-Shopify-Access-Token", _accessToken);

        var response = await _httpClient.SendAsync(request);
        response.EnsureSuccessStatusCode();

        var content = await response.Content.ReadAsStringAsync();
        var data = JsonConvert.DeserializeObject<ShopifyApiResponse<T>>(content);

        return data?.Items ?? Enumerable.Empty<T>();
    }
}

public class ShopifyApiResponse<T>
{
    [JsonProperty("products")] 
    public List<T> Items { get; set; }
}

Vediamo ora come utilizzare il client per avere informazioni sui prodotti.

public class ShopifyProductService
{
    private readonly ShopifyClient<ShopifyProduct> _productClient;

    public ShopifyProductService(string shopifyUrl, string accessToken)
    {
        _productClient = new ShopifyClient<ShopifyProduct>(shopifyUrl, accessToken);
    }

    public async Task<IEnumerable<ShopifyProduct>> GetAllProductsAsync()
    {
        return await _productClient.GetAllAsync();
    }
}

La classe è poi facilmente estendibile. Possiamo ad esempio aggiungere un metodo che ci permette di creare un prodotto su Shopify.

public async Task<T> CreateAsync(T entity)
{
    var endpoint = await GetEndpointAsync();
    var requestUrl = $"{_shopifyUrl}/admin/api/2024-01/{endpoint}.json";

    var content = new StringContent(JsonConvert.SerializeObject(entity), Encoding.UTF8, "application/json");
    using var request = new HttpRequestMessage(HttpMethod.Post, requestUrl)
    {
        Headers = { { "X-Shopify-Access-Token", _accessToken } },
        Content = content
    };

    var response = await _httpClient.SendAsync(request);
    response.EnsureSuccessStatusCode();

    var responseContent = await response.Content.ReadAsStringAsync();
    return JsonConvert.DeserializeObject<ShopifyApiResponse<T>>(responseContent)?.Items.FirstOrDefault();
}

Conclusione

In questo semplice esempio abbiamo visto come utilizzare i Generics per sviluppare una semplice libreria che permette al nostro codice C# di collegarsi con un servizio esterno com Shopify.


Pubblicato

in

da

Tag: