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 { /// /// 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). /// public class CatalogService : ICatalogService { private readonly ILogger _logger; private readonly IRepository _itemRepository; private readonly IAsyncRepository _brandRepository; private readonly IAsyncRepository _typeRepository; private readonly IUriComposer _uriComposer; public CatalogService( ILoggerFactory loggerFactory, IRepository itemRepository, IAsyncRepository brandRepository, IAsyncRepository typeRepository, IUriComposer uriComposer) { _logger = loggerFactory.CreateLogger(); _itemRepository = itemRepository; _brandRepository = brandRepository; _typeRepository = typeRepository; _uriComposer = uriComposer; } public async Task 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> GetBrands() { _logger.LogInformation("GetBrands called."); var brands = await _brandRepository.ListAllAsync(); var items = new List { 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> GetTypes() { _logger.LogInformation("GetTypes called."); var types = await _typeRepository.ListAllAsync(); var items = new List { 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; } } }