diff --git a/src/ApplicationCore/ApplicationCore.csproj b/src/ApplicationCore/ApplicationCore.csproj index 11dff61..c86812d 100644 --- a/src/ApplicationCore/ApplicationCore.csproj +++ b/src/ApplicationCore/ApplicationCore.csproj @@ -7,7 +7,7 @@ - + diff --git a/src/ApplicationCore/Specifications/BasketWithItemsSpecification.cs b/src/ApplicationCore/Specifications/BasketWithItemsSpecification.cs index 68eeb31..c716db3 100644 --- a/src/ApplicationCore/Specifications/BasketWithItemsSpecification.cs +++ b/src/ApplicationCore/Specifications/BasketWithItemsSpecification.cs @@ -3,16 +3,20 @@ using Microsoft.eShopWeb.ApplicationCore.Entities.BasketAggregate; namespace Microsoft.eShopWeb.ApplicationCore.Specifications { - public sealed class BasketWithItemsSpecification : BaseSpecification + public sealed class BasketWithItemsSpecification : Specification { - public BasketWithItemsSpecification(int basketId) : base(b => b.Id == basketId) + public BasketWithItemsSpecification(int basketId) { - AddInclude(b => b.Items); + Query + .Where(b => b.Id == basketId) + .Include(b => b.Items); } - public BasketWithItemsSpecification(string buyerId) : base(b => b.BuyerId == buyerId) + public BasketWithItemsSpecification(string buyerId) { - AddInclude(b => b.Items); + Query + .Where(b => b.BuyerId == buyerId) + .Include(b => b.Items); } } } diff --git a/src/ApplicationCore/Specifications/CatalogFilterPaginatedSpecification.cs b/src/ApplicationCore/Specifications/CatalogFilterPaginatedSpecification.cs index 8bbdf04..f3d0954 100644 --- a/src/ApplicationCore/Specifications/CatalogFilterPaginatedSpecification.cs +++ b/src/ApplicationCore/Specifications/CatalogFilterPaginatedSpecification.cs @@ -3,13 +3,15 @@ using Microsoft.eShopWeb.ApplicationCore.Entities; namespace Microsoft.eShopWeb.ApplicationCore.Specifications { - public class CatalogFilterPaginatedSpecification : BaseSpecification + public class CatalogFilterPaginatedSpecification : Specification { public CatalogFilterPaginatedSpecification(int skip, int take, int? brandId, int? typeId) - : base(i => (!brandId.HasValue || i.CatalogBrandId == brandId) && - (!typeId.HasValue || i.CatalogTypeId == typeId)) + : base() { - ApplyPaging(skip, take); + Query + .Where(i => (!brandId.HasValue || i.CatalogBrandId == brandId) && + (!typeId.HasValue || i.CatalogTypeId == typeId)) + .Paginate(skip, take); } } } diff --git a/src/ApplicationCore/Specifications/CatalogFilterSpecification.cs b/src/ApplicationCore/Specifications/CatalogFilterSpecification.cs index fc68b8a..9a204ad 100644 --- a/src/ApplicationCore/Specifications/CatalogFilterSpecification.cs +++ b/src/ApplicationCore/Specifications/CatalogFilterSpecification.cs @@ -3,13 +3,12 @@ using Microsoft.eShopWeb.ApplicationCore.Entities; namespace Microsoft.eShopWeb.ApplicationCore.Specifications { - - public class CatalogFilterSpecification : BaseSpecification + public class CatalogFilterSpecification : Specification { public CatalogFilterSpecification(int? brandId, int? typeId) - : base(i => (!brandId.HasValue || i.CatalogBrandId == brandId) && - (!typeId.HasValue || i.CatalogTypeId == typeId)) { + Query.Where(i => (!brandId.HasValue || i.CatalogBrandId == brandId) && + (!typeId.HasValue || i.CatalogTypeId == typeId)); } } } diff --git a/src/ApplicationCore/Specifications/CatalogItemsSpecification.cs b/src/ApplicationCore/Specifications/CatalogItemsSpecification.cs index d514e58..05bb1ec 100644 --- a/src/ApplicationCore/Specifications/CatalogItemsSpecification.cs +++ b/src/ApplicationCore/Specifications/CatalogItemsSpecification.cs @@ -5,11 +5,11 @@ using System.Linq; namespace Microsoft.eShopWeb.ApplicationCore.Specifications { - public class CatalogItemsSpecification : BaseSpecification + public class CatalogItemsSpecification : Specification { - public CatalogItemsSpecification(params int[] ids) : base(c => ids.Contains(c.Id)) + public CatalogItemsSpecification(params int[] ids) { - + Query.Where(c => ids.Contains(c.Id)); } } } diff --git a/src/ApplicationCore/Specifications/CustomerOrdersWithItemsSpecification.cs b/src/ApplicationCore/Specifications/CustomerOrdersWithItemsSpecification.cs index 2d673f7..12b7659 100644 --- a/src/ApplicationCore/Specifications/CustomerOrdersWithItemsSpecification.cs +++ b/src/ApplicationCore/Specifications/CustomerOrdersWithItemsSpecification.cs @@ -1,16 +1,15 @@ using Ardalis.Specification; -using Ardalis.Specification.QueryExtensions.Include; using Microsoft.eShopWeb.ApplicationCore.Entities.OrderAggregate; namespace Microsoft.eShopWeb.ApplicationCore.Specifications { - public class CustomerOrdersWithItemsSpecification : BaseSpecification + public class CustomerOrdersWithItemsSpecification : Specification { public CustomerOrdersWithItemsSpecification(string buyerId) - : base(o => o.BuyerId == buyerId) { - AddIncludes(query => query.Include(o => o.OrderItems) - .ThenInclude(i => i.ItemOrdered)); + Query.Where(o => o.BuyerId == buyerId) + .Include(o => o.OrderItems) + .ThenInclude(i => i.ItemOrdered); } } } diff --git a/src/Infrastructure/Data/EfRepository.cs b/src/Infrastructure/Data/EfRepository.cs index 0d2d222..45f9af1 100644 --- a/src/Infrastructure/Data/EfRepository.cs +++ b/src/Infrastructure/Data/EfRepository.cs @@ -1,4 +1,5 @@ using Ardalis.Specification; +using Ardalis.Specification.EntityFrameworkCore; using Microsoft.EntityFrameworkCore; using Microsoft.eShopWeb.ApplicationCore.Entities; using Microsoft.eShopWeb.ApplicationCore.Interfaces; @@ -34,13 +35,13 @@ namespace Microsoft.eShopWeb.Infrastructure.Data public async Task> ListAsync(ISpecification spec) { - var specificationResult = await ApplySpecification(spec); + var specificationResult = ApplySpecification(spec); return await specificationResult.ToListAsync(); } public async Task CountAsync(ISpecification spec) { - var specificationResult = await ApplySpecification(spec); + var specificationResult = ApplySpecification(spec); return await specificationResult.CountAsync(); } @@ -66,19 +67,20 @@ namespace Microsoft.eShopWeb.Infrastructure.Data public async Task FirstAsync(ISpecification spec) { - var specificationResult = await ApplySpecification(spec); + var specificationResult = ApplySpecification(spec); return await specificationResult.FirstAsync(); } public async Task FirstOrDefaultAsync(ISpecification spec) { - var specificationResult = await ApplySpecification(spec); + var specificationResult = ApplySpecification(spec); return await specificationResult.FirstOrDefaultAsync(); } - private async Task> ApplySpecification(ISpecification spec) + private IQueryable ApplySpecification(ISpecification spec) { - return await EfSpecificationEvaluator.GetQuery(_dbContext.Set().AsQueryable(), spec); + var evaluator = new SpecificationEvaluator(); + return evaluator.GetQuery(_dbContext.Set().AsQueryable(), spec); } } } \ No newline at end of file diff --git a/src/Infrastructure/Infrastructure.csproj b/src/Infrastructure/Infrastructure.csproj index c2ff1c9..87034d1 100644 --- a/src/Infrastructure/Infrastructure.csproj +++ b/src/Infrastructure/Infrastructure.csproj @@ -7,7 +7,8 @@ - + + diff --git a/src/Web/Areas/Identity/Pages/Account/Login.cshtml b/src/Web/Areas/Identity/Pages/Account/Login.cshtml index 97c524d..c512527 100644 --- a/src/Web/Areas/Identity/Pages/Account/Login.cshtml +++ b/src/Web/Areas/Identity/Pages/Account/Login.cshtml @@ -47,7 +47,7 @@ Note that for demo purposes you don't need to register and can login with these credentials:

- User: demouser@microsoft.com + User: demouser@microsoft.com OR admin@microsoft.com

Password: Pass@word1 diff --git a/src/Web/Web.csproj b/src/Web/Web.csproj index 74ea66b..0f44a06 100644 --- a/src/Web/Web.csproj +++ b/src/Web/Web.csproj @@ -22,7 +22,7 @@ - + diff --git a/tests/UnitTests/ApplicationCore/Specifications/BasketWithItemsSpecification.cs b/tests/UnitTests/ApplicationCore/Specifications/BasketWithItemsSpecification.cs index 401fce1..048d504 100644 --- a/tests/UnitTests/ApplicationCore/Specifications/BasketWithItemsSpecification.cs +++ b/tests/UnitTests/ApplicationCore/Specifications/BasketWithItemsSpecification.cs @@ -4,22 +4,25 @@ using System.Collections.Generic; using System.Linq; using Xunit; using Moq; +using Ardalis.Specification.EntityFrameworkCore; -namespace Microsoft.eShopWeb.UnitTests +namespace Microsoft.eShopWeb.UnitTests.ApplicationCore.Specifications { public class BasketWithItems { private readonly int _testBasketId = 123; private readonly string _buyerId = "Test buyerId"; + // tests with specifications can use an evaluator or just WhereExpressions.FirstOrDefault if only one + private readonly SpecificationEvaluator _evaluator = new SpecificationEvaluator(); + [Fact] public void MatchesBasketWithGivenBasketId() { var spec = new BasketWithItemsSpecification(_testBasketId); - var result = GetTestBasketCollection() - .AsQueryable() - .FirstOrDefault(spec.Criterias.FirstOrDefault()); + var result = _evaluator.GetQuery(GetTestBasketCollection().AsQueryable(), spec) + .FirstOrDefault(); Assert.NotNull(result); Assert.Equal(_testBasketId, result.Id); @@ -31,9 +34,10 @@ namespace Microsoft.eShopWeb.UnitTests int badBasketId = -1; var spec = new BasketWithItemsSpecification(badBasketId); - Assert.False(GetTestBasketCollection() - .AsQueryable() - .Any(spec.Criterias.FirstOrDefault())); + var result = _evaluator.GetQuery(GetTestBasketCollection().AsQueryable(), spec) + .Any(); + + Assert.False(result); } [Fact] @@ -41,9 +45,8 @@ namespace Microsoft.eShopWeb.UnitTests { var spec = new BasketWithItemsSpecification(_buyerId); - var result = GetTestBasketCollection() - .AsQueryable() - .FirstOrDefault(spec.Criterias.FirstOrDefault()); + var result = _evaluator.GetQuery(GetTestBasketCollection().AsQueryable(), spec) + .FirstOrDefault(); Assert.NotNull(result); Assert.Equal(_buyerId, result.BuyerId); @@ -55,9 +58,10 @@ namespace Microsoft.eShopWeb.UnitTests string badBuyerId = "badBuyerId"; var spec = new BasketWithItemsSpecification(badBuyerId); - Assert.False(GetTestBasketCollection() - .AsQueryable() - .Any(spec.Criterias.FirstOrDefault())); + var result = _evaluator.GetQuery(GetTestBasketCollection().AsQueryable(), spec) + .Any(); + + Assert.False(result); } public List GetTestBasketCollection() diff --git a/tests/UnitTests/ApplicationCore/Specifications/CatalogFilterPaginatedSpecification.cs b/tests/UnitTests/ApplicationCore/Specifications/CatalogFilterPaginatedSpecification.cs index 6f0d66a..7592c19 100644 --- a/tests/UnitTests/ApplicationCore/Specifications/CatalogFilterPaginatedSpecification.cs +++ b/tests/UnitTests/ApplicationCore/Specifications/CatalogFilterPaginatedSpecification.cs @@ -14,7 +14,7 @@ namespace Microsoft.eShopWeb.UnitTests.ApplicationCore.Specifications var result = GetTestCollection() .AsQueryable() - .Where(spec.Criterias.FirstOrDefault()); + .Where(spec.WhereExpressions.FirstOrDefault()); Assert.NotNull(result); Assert.Equal(4, result.ToList().Count); @@ -27,7 +27,7 @@ namespace Microsoft.eShopWeb.UnitTests.ApplicationCore.Specifications var result = GetTestCollection() .AsQueryable() - .Where(spec.Criterias.FirstOrDefault()); + .Where(spec.WhereExpressions.FirstOrDefault()); Assert.NotNull(result); Assert.Equal(2, result.ToList().Count); diff --git a/tests/UnitTests/ApplicationCore/Specifications/CatalogFilterSpecification.cs b/tests/UnitTests/ApplicationCore/Specifications/CatalogFilterSpecification.cs index 681e78b..8b9c5a7 100644 --- a/tests/UnitTests/ApplicationCore/Specifications/CatalogFilterSpecification.cs +++ b/tests/UnitTests/ApplicationCore/Specifications/CatalogFilterSpecification.cs @@ -3,7 +3,7 @@ using System.Collections.Generic; using System.Linq; using Xunit; -namespace Microsoft.eShopWeb.UnitTests +namespace Microsoft.eShopWeb.UnitTests.ApplicationCore.Specifications { public class CatalogFilterSpecification { @@ -21,7 +21,7 @@ namespace Microsoft.eShopWeb.UnitTests var result = GetTestItemCollection() .AsQueryable() - .Where(spec.Criterias.FirstOrDefault()); + .Where(spec.WhereExpressions.FirstOrDefault()); Assert.Equal(expectedCount, result.Count()); } diff --git a/tests/UnitTests/ApplicationCore/Specifications/CatalogItemsSpecification.cs b/tests/UnitTests/ApplicationCore/Specifications/CatalogItemsSpecification.cs index 2f9f11d..0f8e4c5 100644 --- a/tests/UnitTests/ApplicationCore/Specifications/CatalogItemsSpecification.cs +++ b/tests/UnitTests/ApplicationCore/Specifications/CatalogItemsSpecification.cs @@ -16,7 +16,7 @@ namespace Microsoft.eShopWeb.UnitTests.ApplicationCore.Specifications var result = GetTestCollection() .AsQueryable() - .Where(spec.Criterias.FirstOrDefault()); + .Where(spec.WhereExpressions.FirstOrDefault()); Assert.NotNull(result); Assert.Single(result.ToList()); @@ -30,7 +30,7 @@ namespace Microsoft.eShopWeb.UnitTests.ApplicationCore.Specifications var result = GetTestCollection() .AsQueryable() - .Where(spec.Criterias.FirstOrDefault()); + .Where(spec.WhereExpressions.FirstOrDefault()); Assert.NotNull(result); Assert.Equal(2, result.ToList().Count); diff --git a/tests/UnitTests/ApplicationCore/Specifications/CustomerOrdersWithItemsSpecification.cs b/tests/UnitTests/ApplicationCore/Specifications/CustomerOrdersWithItemsSpecification.cs index 32ffe9e..2ef8420 100644 --- a/tests/UnitTests/ApplicationCore/Specifications/CustomerOrdersWithItemsSpecification.cs +++ b/tests/UnitTests/ApplicationCore/Specifications/CustomerOrdersWithItemsSpecification.cs @@ -17,7 +17,7 @@ namespace Microsoft.eShopWeb.UnitTests.ApplicationCore.Specifications var result = GetTestCollection() .AsQueryable() - .FirstOrDefault(spec.Criterias.FirstOrDefault()); + .FirstOrDefault(spec.WhereExpressions.FirstOrDefault()); Assert.NotNull(result); Assert.NotNull(result.OrderItems); @@ -32,7 +32,7 @@ namespace Microsoft.eShopWeb.UnitTests.ApplicationCore.Specifications var result = GetTestCollection() .AsQueryable() - .Where(spec.Criterias.FirstOrDefault()) + .Where(spec.WhereExpressions.FirstOrDefault()) .ToList(); Assert.NotNull(result);