make : // TODO: Make a generic service for any LookupData type (#594)

* make :  // TODO: Make a generic service for any LookupData type => CatalogLookupDataService

* Update src/BlazorAdmin/Services/CachedCatalogTypeServiceDecorator.cs

Co-authored-by: Steve Smith <steve@kentsmiths.com>
This commit is contained in:
Cédric Michel
2021-10-26 16:59:50 +02:00
committed by GitHub
parent 8f55b1b56a
commit f6a975acbe
18 changed files with 122 additions and 140 deletions

View File

@@ -1,8 +1,8 @@
using BlazorAdmin.Helpers;
using System.Collections.Generic;
using System.Threading.Tasks;
using BlazorShared.Interfaces;
using BlazorShared.Models;
using System.Collections.Generic;
using System.Threading.Tasks;
namespace BlazorAdmin.Pages.CatalogItemPage
{
@@ -12,10 +12,10 @@ namespace BlazorAdmin.Pages.CatalogItemPage
public ICatalogItemService CatalogItemService { get; set; }
[Microsoft.AspNetCore.Components.Inject]
public ICatalogBrandService CatalogBrandService { get; set; }
public ICatalogLookupDataService<CatalogBrand> CatalogBrandService { get; set; }
[Microsoft.AspNetCore.Components.Inject]
public ICatalogTypeService CatalogTypeService { get; set; }
public ICatalogLookupDataService<CatalogType> CatalogTypeService { get; set; }
private List<CatalogItem> catalogItems = new List<CatalogItem>();
private List<CatalogType> catalogTypes = new List<CatalogType>();

View File

@@ -9,15 +9,15 @@ using System.Threading.Tasks;
namespace BlazorAdmin.Services
{
public class CachedCatalogBrandServiceDecorator : ICatalogBrandService
public class CachedCatalogBrandServiceDecorator : ICatalogLookupDataService<CatalogBrand>
{
// TODO: Make a generic decorator for any LookupData type
private readonly ILocalStorageService _localStorageService;
private readonly CatalogBrandService _catalogBrandService;
private readonly CatalogLookupDataService<CatalogBrand, CatalogBrandResponse> _catalogBrandService;
private ILogger<CachedCatalogBrandServiceDecorator> _logger;
public CachedCatalogBrandServiceDecorator(ILocalStorageService localStorageService,
CatalogBrandService catalogBrandService,
CatalogLookupDataService<CatalogBrand, CatalogBrandResponse> catalogBrandService,
ILogger<CachedCatalogBrandServiceDecorator> logger)
{
_localStorageService = localStorageService;

View File

@@ -9,15 +9,14 @@ using System.Threading.Tasks;
namespace BlazorAdmin.Services
{
public class CachedCatalogTypeServiceDecorator : ICatalogTypeService
public class CachedCatalogTypeServiceDecorator : ICatalogLookupDataService<CatalogType>
{
// TODO: Make a generic decorator for any LookupData type
private readonly ILocalStorageService _localStorageService;
private readonly CatalogTypeService _catalogTypeService;
private readonly CatalogLookupDataService<CatalogType, CatalogTypeResponse> _catalogTypeService;
private ILogger<CachedCatalogTypeServiceDecorator> _logger;
public CachedCatalogTypeServiceDecorator(ILocalStorageService localStorageService,
CatalogTypeService catalogTypeService,
CatalogLookupDataService<CatalogType, CatalogTypeResponse> catalogTypeService,
ILogger<CachedCatalogTypeServiceDecorator> logger)
{
_localStorageService = localStorageService;

View File

@@ -1,41 +0,0 @@
using BlazorShared;
using BlazorShared.Interfaces;
using BlazorShared.Models;
using Microsoft.Extensions.Logging;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Net.Http.Json;
using System.Threading.Tasks;
namespace BlazorAdmin.Services
{
public class CatalogBrandService : ICatalogBrandService
{
// TODO: Make a generic service for any LookupData type
private readonly HttpClient _httpClient;
private readonly ILogger<CatalogBrandService> _logger;
private string _apiUrl;
public CatalogBrandService(HttpClient httpClient,
BaseUrlConfiguration baseUrlConfiguration,
ILogger<CatalogBrandService> logger)
{
_httpClient = httpClient;
_logger = logger;
_apiUrl = baseUrlConfiguration.ApiBase;
}
public async Task<CatalogBrand> GetById(int id)
{
return (await List()).FirstOrDefault(x => x.Id == id);
}
public async Task<List<CatalogBrand>> List()
{
_logger.LogInformation("Fetching brands from API.");
return (await _httpClient.GetFromJsonAsync<CatalogBrandResponse>($"{_apiUrl}catalog-brands"))?.CatalogBrands;
}
}
}

View File

@@ -1,5 +1,4 @@
using BlazorShared;
using BlazorShared.Interfaces;
using BlazorShared.Interfaces;
using BlazorShared.Models;
using Microsoft.Extensions.Logging;
using System.Collections.Generic;
@@ -11,24 +10,20 @@ namespace BlazorAdmin.Services
{
public class CatalogItemService : ICatalogItemService
{
private readonly ICatalogBrandService _brandService;
private readonly ICatalogTypeService _typeService;
private readonly ICatalogLookupDataService<CatalogBrand> _brandService;
private readonly ICatalogLookupDataService<CatalogType> _typeService;
private readonly HttpService _httpService;
private readonly ILogger<CatalogItemService> _logger;
private string _apiUrl;
public CatalogItemService(ICatalogBrandService brandService,
ICatalogTypeService typeService,
public CatalogItemService(ICatalogLookupDataService<CatalogBrand> brandService,
ICatalogLookupDataService<CatalogType> typeService,
HttpService httpService,
BaseUrlConfiguration baseUrlConfiguration,
ILogger<CatalogItemService> logger)
{
_brandService = brandService;
_typeService = typeService;
_httpService = httpService;
_logger = logger;
_apiUrl = baseUrlConfiguration.ApiBase;
}
public async Task<CatalogItem> Create(CreateCatalogItemRequest catalogItem)
@@ -85,7 +80,7 @@ namespace BlazorAdmin.Services
_logger.LogInformation("Fetching catalog items from API.");
var brandListTask = _brandService.List();
var typeListTask = _typeService.List();
var typeListTask = _typeService.List();
var itemListTask = _httpService.HttpGet<PagedCatalogItemResponse>($"catalog-items");
await Task.WhenAll(brandListTask, typeListTask, itemListTask);
var brands = brandListTask.Result;

View File

@@ -0,0 +1,48 @@
using BlazorShared;
using BlazorShared.Attributes;
using BlazorShared.Interfaces;
using BlazorShared.Models;
using Microsoft.Extensions.Logging;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Net.Http.Json;
using System.Reflection;
using System.Threading.Tasks;
namespace BlazorAdmin.Services
{
public class CatalogLookupDataService<TLookupData, TReponse>
: ICatalogLookupDataService<TLookupData>
where TLookupData : LookupData
where TReponse : ILookupDataResponse<TLookupData>
{
private readonly HttpClient _httpClient;
private readonly ILogger<CatalogLookupDataService<TLookupData, TReponse>> _logger;
private readonly string _apiUrl;
public CatalogLookupDataService(HttpClient httpClient,
BaseUrlConfiguration baseUrlConfiguration,
ILogger<CatalogLookupDataService<TLookupData, TReponse>> logger)
{
_httpClient = httpClient;
_logger = logger;
_apiUrl = baseUrlConfiguration.ApiBase;
}
public async Task<TLookupData> GetById(int id)
{
return (await List()).FirstOrDefault(x => x.Id == id);
}
public async Task<List<TLookupData>> List()
{
var endpointName = typeof(TLookupData).GetCustomAttribute<EndpointAttribute>().Name;
_logger.LogInformation($"Fetching {typeof(TLookupData).Name} from API. Enpoint : {endpointName}");
var response = await _httpClient.GetFromJsonAsync<TReponse>($"{_apiUrl}{endpointName}");
return response.List;
}
}
}

View File

@@ -1,40 +0,0 @@
using BlazorShared;
using BlazorShared.Interfaces;
using BlazorShared.Models;
using Microsoft.Extensions.Logging;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Net.Http.Json;
using System.Threading.Tasks;
namespace BlazorAdmin.Services
{
public class CatalogTypeService : ICatalogTypeService
{
// TODO: Make a generic service for any LookupData type
private readonly HttpClient _httpClient;
private readonly ILogger<CatalogTypeService> _logger;
private string _apiUrl;
public CatalogTypeService(HttpClient httpClient,
BaseUrlConfiguration baseUrlConfiguration,
ILogger<CatalogTypeService> logger)
{
_httpClient = httpClient;
_logger = logger;
_apiUrl = baseUrlConfiguration.ApiBase;
}
public async Task<CatalogType> GetById(int id)
{
return (await List()).FirstOrDefault(x => x.Id == id);
}
public async Task<List<CatalogType>> List()
{
_logger.LogInformation("Fetching types from API.");
return (await _httpClient.GetFromJsonAsync<CatalogTypeResponse>($"{_apiUrl}catalog-types"))?.CatalogTypes;
}
}
}

View File

@@ -1,5 +1,6 @@
using BlazorAdmin.Services;
using BlazorShared.Interfaces;
using BlazorShared.Models;
using Microsoft.Extensions.DependencyInjection;
namespace BlazorAdmin
@@ -8,10 +9,10 @@ namespace BlazorAdmin
{
public static IServiceCollection AddBlazorServices(this IServiceCollection services)
{
services.AddScoped<ICatalogBrandService, CachedCatalogBrandServiceDecorator>();
services.AddScoped<CatalogBrandService>();
services.AddScoped<ICatalogTypeService, CachedCatalogTypeServiceDecorator>();
services.AddScoped<CatalogTypeService>();
services.AddScoped<ICatalogLookupDataService<CatalogBrand>, CachedCatalogBrandServiceDecorator>();
services.AddScoped<CatalogLookupDataService<CatalogBrand, CatalogBrandResponse>>();
services.AddScoped<ICatalogLookupDataService<CatalogType>, CachedCatalogTypeServiceDecorator>();
services.AddScoped<CatalogLookupDataService<CatalogType, CatalogTypeResponse>>();
services.AddScoped<ICatalogItemService, CachedCatalogItemServiceDecorator>();
services.AddScoped<CatalogItemService>();

View File

@@ -0,0 +1,9 @@
using System;
namespace BlazorShared.Attributes
{
public class EndpointAttribute : Attribute
{
public string Name { get; set; }
}
}

View File

@@ -1,12 +0,0 @@
using System.Collections.Generic;
using System.Threading.Tasks;
using BlazorShared.Models;
namespace BlazorShared.Interfaces
{
public interface ICatalogBrandService
{
Task<List<CatalogBrand>> List();
Task<CatalogBrand> GetById(int id);
}
}

View File

@@ -0,0 +1,12 @@
using BlazorShared.Models;
using System.Collections.Generic;
using System.Threading.Tasks;
namespace BlazorShared.Interfaces
{
public interface ICatalogLookupDataService<TLookupData> where TLookupData : LookupData
{
Task<List<TLookupData>> List();
Task<TLookupData> GetById(int id);
}
}

View File

@@ -1,12 +0,0 @@
using BlazorShared.Models;
using System.Collections.Generic;
using System.Threading.Tasks;
namespace BlazorShared.Interfaces
{
public interface ICatalogTypeService
{
Task<List<CatalogType>> List();
Task<CatalogType> GetById(int id);
}
}

View File

@@ -0,0 +1,10 @@
using BlazorShared.Models;
using System.Collections.Generic;
namespace BlazorShared.Interfaces
{
public interface ILookupDataResponse<TLookupData> where TLookupData : LookupData
{
List<TLookupData> List { get; set; }
}
}

View File

@@ -1,5 +1,8 @@
namespace BlazorShared.Models
using BlazorShared.Attributes;
namespace BlazorShared.Models
{
[Endpoint(Name = "catalog-brands")]
public class CatalogBrand : LookupData
{
}

View File

@@ -1,9 +1,12 @@
using System.Collections.Generic;
using BlazorShared.Interfaces;
using System.Collections.Generic;
using System.Text.Json.Serialization;
namespace BlazorShared.Models
{
public class CatalogBrandResponse
public class CatalogBrandResponse : ILookupDataResponse<CatalogBrand>
{
public List<CatalogBrand> CatalogBrands { get; set; } = new List<CatalogBrand>();
[JsonPropertyName("CatalogBrands")]
public List<CatalogBrand> List { get; set; } = new List<CatalogBrand>();
}
}

View File

@@ -1,5 +1,8 @@
namespace BlazorShared.Models
using BlazorShared.Attributes;
namespace BlazorShared.Models
{
[Endpoint(Name = "catalog-types")]
public class CatalogType : LookupData
{
}

View File

@@ -1,9 +1,13 @@
using System.Collections.Generic;
using BlazorShared.Interfaces;
using System.Collections.Generic;
using System.Text.Json.Serialization;
namespace BlazorShared.Models
{
public class CatalogTypeResponse
public class CatalogTypeResponse : ILookupDataResponse<CatalogType>
{
public List<CatalogType> CatalogTypes { get; set; } = new List<CatalogType>();
[JsonPropertyName("CatalogTypes")]
public List<CatalogType> List { get; set; } = new List<CatalogType>();
}
}

View File

@@ -1,7 +1,7 @@
namespace BlazorShared.Models
{
public abstract class LookupData
{
{
public int Id { get; set; }
public string Name { get; set; }
}