Skip to content

Commit

Permalink
Merge pull request dotnet-architecture#221 from dotnet-architecture/r…
Browse files Browse the repository at this point in the history
…emove-irepository

Removing IRepository in favor of IAsyncRepository
  • Loading branch information
efleming18 authored Mar 9, 2019
2 parents 239d217 + 8a00269 commit 82c8f56
Show file tree
Hide file tree
Showing 11 changed files with 46 additions and 104 deletions.
17 changes: 0 additions & 17 deletions src/ApplicationCore/Interfaces/IRepository.cs

This file was deleted.

3 changes: 0 additions & 3 deletions src/ApplicationCore/Services/BasketService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,18 +15,15 @@ public class BasketService : IBasketService
private readonly IAsyncRepository<BasketItem> _basketItemRepository;
private readonly IUriComposer _uriComposer;
private readonly IAppLogger<BasketService> _logger;
private readonly IRepository<CatalogItem> _itemRepository;

public BasketService(IAsyncRepository<Basket> basketRepository,
IRepository<CatalogItem> itemRepository,
IUriComposer uriComposer,
IAppLogger<BasketService> logger,
IAsyncRepository<BasketItem> basketItemRepository)
{
_basketRepository = basketRepository;
_uriComposer = uriComposer;
_logger = logger;
_itemRepository = itemRepository;
_basketItemRepository = basketItemRepository;
}

Expand Down
50 changes: 3 additions & 47 deletions src/Infrastructure/Data/EfRepository.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,92 +12,48 @@ namespace Microsoft.eShopWeb.Infrastructure.Data
/// https://blogs.msdn.microsoft.com/pfxteam/2012/04/13/should-i-expose-synchronous-wrappers-for-asynchronous-methods/
/// </summary>
/// <typeparam name="T"></typeparam>
public class EfRepository<T> : IRepository<T>, IAsyncRepository<T> where T : BaseEntity
public class EfRepository<T> : IAsyncRepository<T> where T : BaseEntity
{
protected readonly CatalogContext _dbContext;

public EfRepository(CatalogContext dbContext)
{
_dbContext = dbContext;
}

public virtual T GetById(int id)
{
return _dbContext.Set<T>().Find(id);
}

public T GetSingleBySpec(ISpecification<T> spec)
{
return List(spec).FirstOrDefault();
}


public virtual async Task<T> GetByIdAsync(int id)
{
return await _dbContext.Set<T>().FindAsync(id);
}

public IEnumerable<T> ListAll()
{
return _dbContext.Set<T>().AsEnumerable();
}


public async Task<IReadOnlyList<T>> ListAllAsync()
{
return await _dbContext.Set<T>().ToListAsync();
}

public IEnumerable<T> List(ISpecification<T> spec)
{
return ApplySpecification(spec).AsEnumerable();
}
public async Task<IReadOnlyList<T>> ListAsync(ISpecification<T> spec)
{
return await ApplySpecification(spec).ToListAsync();
}

public int Count(ISpecification<T> spec)
{
return ApplySpecification(spec).Count();
}

public async Task<int> CountAsync(ISpecification<T> spec)
{
return await ApplySpecification(spec).CountAsync();
}

public T Add(T entity)
{
_dbContext.Set<T>().Add(entity);
_dbContext.SaveChanges();

return entity;
}

public async Task<T> AddAsync(T entity)
{
_dbContext.Set<T>().Add(entity);
await _dbContext.SaveChangesAsync();

return entity;
}

public void Update(T entity)
{
_dbContext.Entry(entity).State = EntityState.Modified;
_dbContext.SaveChanges();
}

public async Task UpdateAsync(T entity)
{
_dbContext.Entry(entity).State = EntityState.Modified;
await _dbContext.SaveChangesAsync();
}

public void Delete(T entity)
{
_dbContext.Set<T>().Remove(entity);
_dbContext.SaveChanges();
}

public async Task DeleteAsync(T entity)
{
Expand Down
46 changes: 26 additions & 20 deletions src/Web/Services/BasketViewModelService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,10 @@ public class BasketViewModelService : IBasketViewModelService
{
private readonly IAsyncRepository<Basket> _basketRepository;
private readonly IUriComposer _uriComposer;
private readonly IRepository<CatalogItem> _itemRepository;
private readonly IAsyncRepository<CatalogItem> _itemRepository;

public BasketViewModelService(IAsyncRepository<Basket> basketRepository,
IRepository<CatalogItem> itemRepository,
IAsyncRepository<CatalogItem> itemRepository,
IUriComposer uriComposer)
{
_basketRepository = basketRepository;
Expand All @@ -34,30 +34,15 @@ public async Task<BasketViewModel> GetOrCreateBasketForUser(string userName)
{
return await CreateBasketForUser(userName);
}
return CreateViewModelFromBasket(basket);
return await CreateViewModelFromBasket(basket);
}

private BasketViewModel CreateViewModelFromBasket(Basket basket)
private async Task<BasketViewModel> CreateViewModelFromBasket(Basket basket)
{
var viewModel = new BasketViewModel();
viewModel.Id = basket.Id;
viewModel.BuyerId = basket.BuyerId;
viewModel.Items = basket.Items.Select(i =>
{
var itemModel = new BasketItemViewModel()
{
Id = i.Id,
UnitPrice = i.UnitPrice,
Quantity = i.Quantity,
CatalogItemId = i.CatalogItemId

};
var item = _itemRepository.GetById(i.CatalogItemId);
itemModel.PictureUrl = _uriComposer.ComposePicUri(item.PictureUri);
itemModel.ProductName = item.Name;
return itemModel;
})
.ToList();
viewModel.Items = await GetBasketItems(basket.Items); ;
return viewModel;
}

Expand All @@ -73,5 +58,26 @@ private async Task<BasketViewModel> CreateBasketForUser(string userId)
Items = new List<BasketItemViewModel>()
};
}

private async Task<List<BasketItemViewModel>> GetBasketItems(IReadOnlyCollection<BasketItem> basketItems)
{
var items = new List<BasketItemViewModel>();
foreach (var item in basketItems)
{
var itemModel = new BasketItemViewModel
{
Id = item.Id,
UnitPrice = item.UnitPrice,
Quantity = item.Quantity,
CatalogItemId = item.CatalogItemId
};
var catalogItem = await _itemRepository.GetByIdAsync(item.CatalogItemId);
itemModel.PictureUrl = _uriComposer.ComposePicUri(catalogItem.PictureUri);
itemModel.ProductName = catalogItem.Name;
items.Add(itemModel);
}

return items;
}
}
}
14 changes: 7 additions & 7 deletions src/Web/Services/CatalogService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,14 @@ namespace Microsoft.eShopWeb.Web.Services
public class CatalogService : ICatalogService
{
private readonly ILogger<CatalogService> _logger;
private readonly IRepository<CatalogItem> _itemRepository;
private readonly IAsyncRepository<CatalogItem> _itemRepository;
private readonly IAsyncRepository<CatalogBrand> _brandRepository;
private readonly IAsyncRepository<CatalogType> _typeRepository;
private readonly IUriComposer _uriComposer;

public CatalogService(
ILoggerFactory loggerFactory,
IRepository<CatalogItem> itemRepository,
IAsyncRepository<CatalogItem> itemRepository,
IAsyncRepository<CatalogBrand> brandRepository,
IAsyncRepository<CatalogType> typeRepository,
IUriComposer uriComposer)
Expand All @@ -46,13 +46,13 @@ public async Task<CatalogIndexViewModel> GetCatalogItems(int pageIndex, int item
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);
var itemsOnPage = await _itemRepository.ListAsync(filterPaginatedSpecification);
var totalItems = await _itemRepository.CountAsync(filterSpecification);

itemsOnPage.ForEach(x =>
foreach (var itemOnPage in itemsOnPage)
{
x.PictureUri = _uriComposer.ComposePicUri(x.PictureUri);
});
itemOnPage.PictureUri = _uriComposer.ComposePicUri(itemOnPage.PictureUri);
}

var vm = new CatalogIndexViewModel()
{
Expand Down
3 changes: 1 addition & 2 deletions src/Web/Startup.cs
Original file line number Diff line number Diff line change
Expand Up @@ -84,8 +84,7 @@ public void ConfigureServices(IServiceCollection services)
ConfigureCookieSettings(services);

CreateIdentityIfNotCreated(services);

services.AddScoped(typeof(IRepository<>), typeof(EfRepository<>));

services.AddScoped(typeof(IAsyncRepository<>), typeof(EfRepository<>));

services.AddScoped<ICatalogService, CachedCatalogService>();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ public async Task DeleteItemFromBasket()
await _basketItemRepository.DeleteAsync(existingBasket.Items.FirstOrDefault());
_catalogContext.SaveChanges();

var basketFromDB = _basketRepository.GetById(BasketBuilder.BasketId);
var basketFromDB = await _basketRepository.GetByIdAsync(BasketBuilder.BasketId);

Assert.Equal(0, basketFromDB.Items.Count);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using Microsoft.eShopWeb.UnitTests.Builders;
using Xunit;
using Xunit.Abstractions;
using System.Threading.Tasks;

namespace Microsoft.eShopWeb.IntegrationTests.Repositories.OrderRepositoryTests
{
Expand All @@ -24,15 +25,15 @@ public GetById(ITestOutputHelper output)
}

[Fact]
public void GetsExistingOrder()
public async Task GetsExistingOrder()
{
var existingOrder = OrderBuilder.WithDefaultValues();
_catalogContext.Orders.Add(existingOrder);
_catalogContext.SaveChanges();
int orderId = existingOrder.Id;
_output.WriteLine($"OrderId: {orderId}");

var orderFromRepo = _orderRepository.GetById(orderId);
var orderFromRepo = await _orderRepository.GetByIdAsync(orderId);
Assert.Equal(OrderBuilder.TestBuyerId, orderFromRepo.BuyerId);

// Note: Using InMemoryDatabase OrderItems is available. Will be null if using SQL DB.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ public async Task Should_InvokeBasketRepoOnceAndBasketItemRepoTwice_Given_TwoIte
basket.AddItem(2, It.IsAny<decimal>(), It.IsAny<int>());
_mockBasketRepo.Setup(x => x.GetByIdAsync(It.IsAny<int>()))
.ReturnsAsync(basket);
var basketService = new BasketService(_mockBasketRepo.Object, null, null, null, _mockBasketItemRepo.Object);
var basketService = new BasketService(_mockBasketRepo.Object, null, null, _mockBasketItemRepo.Object);

await basketService.DeleteBasketAsync(It.IsAny<int>());

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ public SetQuantities()
[Fact]
public async void ThrowsGivenInvalidBasketId()
{
var basketService = new BasketService(_mockBasketRepo.Object, null, null, null, null);
var basketService = new BasketService(_mockBasketRepo.Object, null, null, null);

await Assert.ThrowsAsync<BasketNotFoundException>(async () =>
await basketService.SetQuantities(_invalidId, new System.Collections.Generic.Dictionary<string, int>()));
Expand All @@ -30,7 +30,7 @@ await Assert.ThrowsAsync<BasketNotFoundException>(async () =>
[Fact]
public async void ThrowsGivenNullQuantities()
{
var basketService = new BasketService(null, null, null, null, null);
var basketService = new BasketService(null, null, null, null);

await Assert.ThrowsAsync<ArgumentNullException>(async () =>
await basketService.SetQuantities(123, null));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,15 @@ public class TransferBasket
[Fact]
public async void ThrowsGivenNullAnonymousId()
{
var basketService = new BasketService(null, null, null, null, null);
var basketService = new BasketService(null, null, null, null);

await Assert.ThrowsAsync<ArgumentNullException>(async () => await basketService.TransferBasketAsync(null, "steve"));
}

[Fact]
public async void ThrowsGivenNullUserId()
{
var basketService = new BasketService(null, null, null, null, null);
var basketService = new BasketService(null, null, null, null);

await Assert.ThrowsAsync<ArgumentNullException>(async () => await basketService.TransferBasketAsync("abcdefg", null));
}
Expand Down

0 comments on commit 82c8f56

Please sign in to comment.