* Paging criterias added in BaseSpecification. New paginated specification added (CatalogFilterPaginatedSpecification) . EFRepository cleaned up and paging implementation added. Usage of the new paging infrastructure in CatalogService (Web and WebRazor). * Use IReadOnlyList<T> instead of List<T> as return type from repositories. * - Ordering possibility added in the specification. - Evaluation of the specification placed in separate class.
119 lines
4.6 KiB
C#
119 lines
4.6 KiB
C#
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Threading.Tasks;
|
|
using Microsoft.AspNetCore.Mvc.Rendering;
|
|
using Microsoft.eShopWeb.Web.ViewModels;
|
|
using Microsoft.eShopWeb.ApplicationCore.Entities;
|
|
using Microsoft.Extensions.Logging;
|
|
using Microsoft.eShopWeb.ApplicationCore.Interfaces;
|
|
using System;
|
|
using Microsoft.eShopWeb.ApplicationCore.Specifications;
|
|
|
|
namespace Microsoft.eShopWeb.Web.Services
|
|
{
|
|
/// <summary>
|
|
/// This is a UI-specific service so belongs in UI project. It does not contain any business logic and works
|
|
/// with UI-specific types (view models and SelectListItem types).
|
|
/// </summary>
|
|
public class CatalogService : ICatalogService
|
|
{
|
|
private readonly ILogger<CatalogService> _logger;
|
|
private readonly IRepository<CatalogItem> _itemRepository;
|
|
private readonly IAsyncRepository<CatalogBrand> _brandRepository;
|
|
private readonly IAsyncRepository<CatalogType> _typeRepository;
|
|
private readonly IUriComposer _uriComposer;
|
|
|
|
public CatalogService(
|
|
ILoggerFactory loggerFactory,
|
|
IRepository<CatalogItem> itemRepository,
|
|
IAsyncRepository<CatalogBrand> brandRepository,
|
|
IAsyncRepository<CatalogType> typeRepository,
|
|
IUriComposer uriComposer)
|
|
{
|
|
_logger = loggerFactory.CreateLogger<CatalogService>();
|
|
_itemRepository = itemRepository;
|
|
_brandRepository = brandRepository;
|
|
_typeRepository = typeRepository;
|
|
_uriComposer = uriComposer;
|
|
}
|
|
|
|
public async Task<CatalogIndexViewModel> GetCatalogItems(int pageIndex, int itemsPage, int? brandId, int? typeId)
|
|
{
|
|
_logger.LogInformation("GetCatalogItems called.");
|
|
|
|
var filterSpecification = new CatalogFilterSpecification(brandId, typeId);
|
|
var filterPaginatedSpecification =
|
|
new CatalogFilterPaginatedSpecification(itemsPage * pageIndex, itemsPage, brandId, typeId);
|
|
|
|
// the implementation below using ForEach and Count. We need a List.
|
|
var itemsOnPage = _itemRepository.List(filterPaginatedSpecification).ToList();
|
|
var totalItems = _itemRepository.Count(filterSpecification);
|
|
|
|
itemsOnPage.ForEach(x =>
|
|
{
|
|
x.PictureUri = _uriComposer.ComposePicUri(x.PictureUri);
|
|
});
|
|
|
|
var vm = new CatalogIndexViewModel()
|
|
{
|
|
CatalogItems = itemsOnPage.Select(i => new CatalogItemViewModel()
|
|
{
|
|
Id = i.Id,
|
|
Name = i.Name,
|
|
PictureUri = i.PictureUri,
|
|
Price = i.Price
|
|
}),
|
|
Brands = await GetBrands(),
|
|
Types = await GetTypes(),
|
|
BrandFilterApplied = brandId ?? 0,
|
|
TypesFilterApplied = typeId ?? 0,
|
|
PaginationInfo = new PaginationInfoViewModel()
|
|
{
|
|
ActualPage = pageIndex,
|
|
ItemsPerPage = itemsOnPage.Count,
|
|
TotalItems = totalItems,
|
|
TotalPages = int.Parse(Math.Ceiling(((decimal)totalItems / itemsPage)).ToString())
|
|
}
|
|
};
|
|
|
|
vm.PaginationInfo.Next = (vm.PaginationInfo.ActualPage == vm.PaginationInfo.TotalPages - 1) ? "is-disabled" : "";
|
|
vm.PaginationInfo.Previous = (vm.PaginationInfo.ActualPage == 0) ? "is-disabled" : "";
|
|
|
|
return vm;
|
|
}
|
|
|
|
public async Task<IEnumerable<SelectListItem>> GetBrands()
|
|
{
|
|
_logger.LogInformation("GetBrands called.");
|
|
var brands = await _brandRepository.ListAllAsync();
|
|
|
|
var items = new List<SelectListItem>
|
|
{
|
|
new SelectListItem() { Value = null, Text = "All", Selected = true }
|
|
};
|
|
foreach (CatalogBrand brand in brands)
|
|
{
|
|
items.Add(new SelectListItem() { Value = brand.Id.ToString(), Text = brand.Brand });
|
|
}
|
|
|
|
return items;
|
|
}
|
|
|
|
public async Task<IEnumerable<SelectListItem>> GetTypes()
|
|
{
|
|
_logger.LogInformation("GetTypes called.");
|
|
var types = await _typeRepository.ListAllAsync();
|
|
var items = new List<SelectListItem>
|
|
{
|
|
new SelectListItem() { Value = null, Text = "All", Selected = true }
|
|
};
|
|
foreach (CatalogType type in types)
|
|
{
|
|
items.Add(new SelectListItem() { Value = type.Id.ToString(), Text = type.Type });
|
|
}
|
|
|
|
return items;
|
|
}
|
|
}
|
|
}
|