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’usoL’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.