Skip to content

Commit

Permalink
Initial Upgrade to .NET Core 2.0 (dotnet-architecture#50)
Browse files Browse the repository at this point in the history
* Ardalis/upgrade1 (dotnet-architecture#44)

* Upgrading to netcore 2.0
Updating repository to support async options and refactoring to use it.

* Starting work on tracking customer orders feature.

* Cleaning up some bugs
Working on basket view component implementation

* Fixing up styles, especially for basket in header.

* Adding Order Features (dotnet-architecture#47)

* Working on order model binding from checkout page - WIP

* Small layout tweaks (dotnet-architecture#43)

* Updating quantities implemented.

* Fixed basket widget count

* Order History (dotnet-architecture#49)

* working on creating and viewing orders.
* Working on wiring up listing of orders
* List orders page works as expected. Needed to support ThenInclude scenarios. Currently using strings.
  • Loading branch information
ardalis authored Sep 22, 2017
1 parent b90bd08 commit aca6183
Show file tree
Hide file tree
Showing 70 changed files with 1,752 additions and 510 deletions.
2 changes: 1 addition & 1 deletion src/ApplicationCore/ApplicationCore.csproj
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>netstandard1.4</TargetFramework>
<TargetFramework>netstandard2.0</TargetFramework>
</PropertyGroup>

<ItemGroup>
Expand Down
26 changes: 26 additions & 0 deletions src/ApplicationCore/Entities/BuyerAggregate/Buyer.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
using ApplicationCore.Interfaces;
using Microsoft.eShopWeb.ApplicationCore.Entities;
using System;
using System.Collections.Generic;
using System.Text;

namespace ApplicationCore.Entities.BuyerAggregate
{
public class Buyer : BaseEntity, IAggregateRoot
{
public string IdentityGuid { get; private set; }

private List<PaymentMethod> _paymentMethods = new List<PaymentMethod>();

public IEnumerable<PaymentMethod> PaymentMethods => _paymentMethods.AsReadOnly();

protected Buyer()
{
}

public Buyer(string identity) : this()
{
IdentityGuid = !string.IsNullOrWhiteSpace(identity) ? identity : throw new ArgumentNullException(nameof(identity));
}
}
}
11 changes: 11 additions & 0 deletions src/ApplicationCore/Entities/BuyerAggregate/PaymentMethod.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
using Microsoft.eShopWeb.ApplicationCore.Entities;

namespace ApplicationCore.Entities.BuyerAggregate
{
public class PaymentMethod : BaseEntity
{
public string Alias { get; set; }
public string CardId { get; set; } // actual card data must be stored in a PCI compliant system, like Stripe
public string Last4 { get; set; }
}
}
39 changes: 39 additions & 0 deletions src/ApplicationCore/Entities/OrderAggregate/Address.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
using System;
using System.Collections.Generic;

namespace ApplicationCore.Entities.OrderAggregate
{
public class Address // ValueObject
{
public String Street { get; private set; }

public String City { get; private set; }

public String State { get; private set; }

public String Country { get; private set; }

public String ZipCode { get; private set; }

private Address() { }

public Address(string street, string city, string state, string country, string zipcode)
{
Street = street;
City = city;
State = state;
Country = country;
ZipCode = zipcode;
}

//protected override IEnumerable<object> GetAtomicValues()
//{
// yield return Street;
// yield return City;
// yield return State;
// yield return Country;
// yield return ZipCode;
//}

}
}
23 changes: 23 additions & 0 deletions src/ApplicationCore/Entities/OrderAggregate/CatalogItemOrdered.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
namespace ApplicationCore.Entities.OrderAggregate
{
/// <summary>
/// Represents the item that was ordered. If catalog item details change, details of
/// the item that was part of a completed order should not change.
/// </summary>
public class CatalogItemOrdered // ValueObject
{
public CatalogItemOrdered(int catalogItemId, string productName, string pictureUri)
{
CatalogItemId = catalogItemId;
ProductName = productName;
PictureUri = pictureUri;
}
private CatalogItemOrdered()
{
// required by EF
}
public int CatalogItemId { get; private set; }
public string ProductName { get; private set; }
public string PictureUri { get; private set; }
}
}
48 changes: 48 additions & 0 deletions src/ApplicationCore/Entities/OrderAggregate/Order.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
using ApplicationCore.Interfaces;
using Microsoft.eShopWeb.ApplicationCore.Entities;
using System;
using System.Collections.Generic;

namespace ApplicationCore.Entities.OrderAggregate
{
public class Order : BaseEntity, IAggregateRoot
{
private Order()
{
}

public Order(string buyerId, Address shipToAddress, List<OrderItem> items)
{
ShipToAddress = shipToAddress;
_orderItems = items;
BuyerId = buyerId;
}
public string BuyerId { get; private set; }

public DateTimeOffset OrderDate { get; private set; } = DateTimeOffset.Now;
public Address ShipToAddress { get; private set; }

// DDD Patterns comment
// Using a private collection field, better for DDD Aggregate's encapsulation
// so OrderItems cannot be added from "outside the AggregateRoot" directly to the collection,
// but only through the method Order.AddOrderItem() which includes behavior.
private readonly List<OrderItem> _orderItems = new List<OrderItem>();

public IReadOnlyCollection<OrderItem> OrderItems => _orderItems;
// Using List<>.AsReadOnly()
// This will create a read only wrapper around the private list so is protected against "external updates".
// It's much cheaper than .ToList() because it will not have to copy all items in a new collection. (Just one heap alloc for the wrapper instance)
//https://msdn.microsoft.com/en-us/library/e78dcd75(v=vs.110).aspx

public decimal Total()
{
var total = 0m;
foreach (var item in _orderItems)
{
total += item.UnitPrice * item.Units;
}
return total;
}

}
}
22 changes: 22 additions & 0 deletions src/ApplicationCore/Entities/OrderAggregate/OrderItem.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
using Microsoft.eShopWeb.ApplicationCore.Entities;

namespace ApplicationCore.Entities.OrderAggregate
{

public class OrderItem : BaseEntity
{
public CatalogItemOrdered ItemOrdered { get; private set; }
public decimal UnitPrice { get; private set; }
public int Units { get; private set; }

protected OrderItem()
{
}
public OrderItem(CatalogItemOrdered itemOrdered, decimal unitPrice, int units)
{
ItemOrdered = itemOrdered;
UnitPrice = unitPrice;
Units = units;
}
}
}
5 changes: 5 additions & 0 deletions src/ApplicationCore/Interfaces/IAggregateRoot.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
namespace ApplicationCore.Interfaces
{
public interface IAggregateRoot
{ }
}
1 change: 1 addition & 0 deletions src/ApplicationCore/Interfaces/IAppLogger.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
/// <typeparam name="T"></typeparam>
public interface IAppLogger<T>
{
void LogInformation(string message, params object[] args);
void LogWarning(string message, params object[] args);
}
}
16 changes: 16 additions & 0 deletions src/ApplicationCore/Interfaces/IAsyncRepository.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
using Microsoft.eShopWeb.ApplicationCore.Entities;
using System.Collections.Generic;
using System.Threading.Tasks;

namespace ApplicationCore.Interfaces
{
public interface IAsyncRepository<T> where T : BaseEntity
{
Task<T> GetByIdAsync(int id);
Task<List<T>> ListAllAsync();
Task<List<T>> ListAsync(ISpecification<T> spec);
Task<T> AddAsync(T entity);
Task UpdateAsync(T entity);
Task DeleteAsync(T entity);
}
}
7 changes: 0 additions & 7 deletions src/ApplicationCore/Interfaces/IImageService.cs

This file was deleted.

12 changes: 12 additions & 0 deletions src/ApplicationCore/Interfaces/IOrderRepository.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
using ApplicationCore.Entities.OrderAggregate;
using System.Threading.Tasks;

namespace ApplicationCore.Interfaces
{

public interface IOrderRepository : IRepository<Order>, IAsyncRepository<Order>
{
Order GetByIdWithItems(int id);
Task<Order> GetByIdWithItemsAsync(int id);
}
}
10 changes: 10 additions & 0 deletions src/ApplicationCore/Interfaces/IOrderService.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
using ApplicationCore.Entities.OrderAggregate;
using System.Threading.Tasks;

namespace ApplicationCore.Interfaces
{
public interface IOrderService
{
Task CreateOrderAsync(int basketId, Address shippingAddress);
}
}
8 changes: 3 additions & 5 deletions src/ApplicationCore/Interfaces/IRepository.cs
Original file line number Diff line number Diff line change
@@ -1,16 +1,14 @@
using Microsoft.eShopWeb.ApplicationCore.Entities;
using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using System.Threading.Tasks;

namespace ApplicationCore.Interfaces
{

public interface IRepository<T> where T : BaseEntity
{
T GetById(int id);
List<T> List();
List<T> List(ISpecification<T> spec);
IEnumerable<T> ListAll();
IEnumerable<T> List(ISpecification<T> spec);
T Add(T entity);
void Update(T entity);
void Delete(T entity);
Expand Down
1 change: 1 addition & 0 deletions src/ApplicationCore/Interfaces/ISpecification.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ public interface ISpecification<T>
{
Expression<Func<T, bool>> Criteria { get; }
List<Expression<Func<T, object>>> Includes { get; }
List<string> IncludeStrings { get; }
void AddInclude(Expression<Func<T, object>> includeExpression);
}
}
6 changes: 1 addition & 5 deletions src/ApplicationCore/Interfaces/IUriComposer.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,5 @@
using Microsoft.eShopWeb.ApplicationCore.Entities;
using System.Collections.Generic;

namespace ApplicationCore.Interfaces
namespace ApplicationCore.Interfaces
{

public interface IUriComposer
{
string ComposePicUri(string uriTemplate);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using System;
using System.Linq.Expressions;
using System.Collections.Generic;
using ApplicationCore.Entities.OrderAggregate;

namespace ApplicationCore.Specifications
{
Expand All @@ -28,6 +29,8 @@ public BasketWithItemsSpecification(string buyerId)

public List<Expression<Func<Basket, object>>> Includes { get; } = new List<Expression<Func<Basket, object>>>();

public List<string> IncludeStrings { get; } = new List<string>();

public void AddInclude(Expression<Func<Basket, object>> includeExpression)
{
Includes.Add(includeExpression);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ public CatalogFilterSpecification(int? brandId, int? typeId)

public List<Expression<Func<CatalogItem, object>>> Includes { get; } = new List<Expression<Func<CatalogItem, object>>>();

public List<string> IncludeStrings { get; } = new List<string>();

public void AddInclude(Expression<Func<CatalogItem, object>> includeExpression)
{
Includes.Add(includeExpression);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
using ApplicationCore.Interfaces;
using System;
using System.Linq.Expressions;
using System.Collections.Generic;
using ApplicationCore.Entities.OrderAggregate;

namespace ApplicationCore.Specifications
{
public class CustomerOrdersWithItemsSpecification : ISpecification<Order>
{
private readonly string _buyerId;

public CustomerOrdersWithItemsSpecification(string buyerId)
{
_buyerId = buyerId;
AddInclude(o => o.OrderItems);
AddInclude("OrderItems.ItemOrdered");
}

public Expression<Func<Order, bool>> Criteria => o => o.BuyerId == _buyerId;

public List<Expression<Func<Order, object>>> Includes { get; } = new List<Expression<Func<Order, object>>>();
public List<string> IncludeStrings { get; } = new List<string>();

public void AddInclude(Expression<Func<Order, object>> includeExpression)
{
Includes.Add(includeExpression);
}

public void AddInclude(string includeString)
{
IncludeStrings.Add(includeString);
}
}
}
Loading

0 comments on commit aca6183

Please sign in to comment.