Shady nagy/net6 (#614)

* udated to .net6

* used the .net6 version RC2

* added editconfig.

* App core new Scoped Namespaces style.

* BlazorAdmin new Scoped Namespaces style.

* Blazor Shared new Scoped Namespaces style.

* Infra new Scoped Namespaces style.

* public api new Scoped Namespaces style.

* web new Scoped Namespaces style.

* FunctionalTests new Scoped Namespaces style.

* Integrational tests new Scoped Namespaces style.

* unit tests new Scoped Namespaces style.

* update github action.

* update github action.

* change the global.
This commit is contained in:
Shady Nagy
2021-11-06 01:55:48 +02:00
committed by GitHub
parent 64f150dc07
commit 9db2feb930
252 changed files with 6307 additions and 6413 deletions

View File

@@ -1,9 +1,8 @@
namespace Microsoft.eShopWeb.ApplicationCore.Entities
namespace Microsoft.eShopWeb.ApplicationCore.Entities;
// This can easily be modified to be BaseEntity<T> and public T Id to support different key types.
// Using non-generic integer types for simplicity and to ease caching logic
public abstract class BaseEntity
{
// This can easily be modified to be BaseEntity<T> and public T Id to support different key types.
// Using non-generic integer types for simplicity and to ease caching logic
public abstract class BaseEntity
{
public virtual int Id { get; protected set; }
}
public virtual int Id { get; protected set; }
}

View File

@@ -1,39 +1,38 @@
using Microsoft.eShopWeb.ApplicationCore.Interfaces;
using System.Collections.Generic;
using System.Collections.Generic;
using System.Linq;
using Microsoft.eShopWeb.ApplicationCore.Interfaces;
namespace Microsoft.eShopWeb.ApplicationCore.Entities.BasketAggregate
namespace Microsoft.eShopWeb.ApplicationCore.Entities.BasketAggregate;
public class Basket : BaseEntity, IAggregateRoot
{
public class Basket : BaseEntity, IAggregateRoot
public string BuyerId { get; private set; }
private readonly List<BasketItem> _items = new List<BasketItem>();
public IReadOnlyCollection<BasketItem> Items => _items.AsReadOnly();
public Basket(string buyerId)
{
public string BuyerId { get; private set; }
private readonly List<BasketItem> _items = new List<BasketItem>();
public IReadOnlyCollection<BasketItem> Items => _items.AsReadOnly();
BuyerId = buyerId;
}
public Basket(string buyerId)
public void AddItem(int catalogItemId, decimal unitPrice, int quantity = 1)
{
if (!Items.Any(i => i.CatalogItemId == catalogItemId))
{
BuyerId = buyerId;
_items.Add(new BasketItem(catalogItemId, quantity, unitPrice));
return;
}
var existingItem = Items.FirstOrDefault(i => i.CatalogItemId == catalogItemId);
existingItem.AddQuantity(quantity);
}
public void AddItem(int catalogItemId, decimal unitPrice, int quantity = 1)
{
if (!Items.Any(i => i.CatalogItemId == catalogItemId))
{
_items.Add(new BasketItem(catalogItemId, quantity, unitPrice));
return;
}
var existingItem = Items.FirstOrDefault(i => i.CatalogItemId == catalogItemId);
existingItem.AddQuantity(quantity);
}
public void RemoveEmptyItems()
{
_items.RemoveAll(i => i.Quantity == 0);
}
public void RemoveEmptyItems()
{
_items.RemoveAll(i => i.Quantity == 0);
}
public void SetNewBuyerId(string buyerId)
{
BuyerId = buyerId;
}
public void SetNewBuyerId(string buyerId)
{
BuyerId = buyerId;
}
}

View File

@@ -1,34 +1,33 @@
using Ardalis.GuardClauses;
namespace Microsoft.eShopWeb.ApplicationCore.Entities.BasketAggregate
namespace Microsoft.eShopWeb.ApplicationCore.Entities.BasketAggregate;
public class BasketItem : BaseEntity
{
public class BasketItem : BaseEntity
public decimal UnitPrice { get; private set; }
public int Quantity { get; private set; }
public int CatalogItemId { get; private set; }
public int BasketId { get; private set; }
public BasketItem(int catalogItemId, int quantity, decimal unitPrice)
{
CatalogItemId = catalogItemId;
UnitPrice = unitPrice;
SetQuantity(quantity);
}
public decimal UnitPrice { get; private set; }
public int Quantity { get; private set; }
public int CatalogItemId { get; private set; }
public int BasketId { get; private set; }
public void AddQuantity(int quantity)
{
Guard.Against.OutOfRange(quantity, nameof(quantity), 0, int.MaxValue);
public BasketItem(int catalogItemId, int quantity, decimal unitPrice)
{
CatalogItemId = catalogItemId;
UnitPrice = unitPrice;
SetQuantity(quantity);
}
Quantity += quantity;
}
public void AddQuantity(int quantity)
{
Guard.Against.OutOfRange(quantity, nameof(quantity), 0, int.MaxValue);
public void SetQuantity(int quantity)
{
Guard.Against.OutOfRange(quantity, nameof(quantity), 0, int.MaxValue);
Quantity += quantity;
}
public void SetQuantity(int quantity)
{
Guard.Against.OutOfRange(quantity, nameof(quantity), 0, int.MaxValue);
Quantity = quantity;
}
Quantity = quantity;
}
}

View File

@@ -1,26 +1,25 @@
using Ardalis.GuardClauses;
using System.Collections.Generic;
using Ardalis.GuardClauses;
using Microsoft.eShopWeb.ApplicationCore.Interfaces;
using System.Collections.Generic;
namespace Microsoft.eShopWeb.ApplicationCore.Entities.BuyerAggregate
namespace Microsoft.eShopWeb.ApplicationCore.Entities.BuyerAggregate;
public class Buyer : BaseEntity, IAggregateRoot
{
public class Buyer : BaseEntity, IAggregateRoot
public string IdentityGuid { get; private set; }
private List<PaymentMethod> _paymentMethods = new List<PaymentMethod>();
public IEnumerable<PaymentMethod> PaymentMethods => _paymentMethods.AsReadOnly();
private Buyer()
{
public string IdentityGuid { get; private set; }
// required by EF
}
private List<PaymentMethod> _paymentMethods = new List<PaymentMethod>();
public IEnumerable<PaymentMethod> PaymentMethods => _paymentMethods.AsReadOnly();
private Buyer()
{
// required by EF
}
public Buyer(string identity) : this()
{
Guard.Against.NullOrEmpty(identity, nameof(identity));
IdentityGuid = identity;
}
public Buyer(string identity) : this()
{
Guard.Against.NullOrEmpty(identity, nameof(identity));
IdentityGuid = identity;
}
}

View File

@@ -1,9 +1,8 @@
namespace Microsoft.eShopWeb.ApplicationCore.Entities.BuyerAggregate
namespace Microsoft.eShopWeb.ApplicationCore.Entities.BuyerAggregate;
public class PaymentMethod : BaseEntity
{
public class PaymentMethod : BaseEntity
{
public string Alias { get; private set; }
public string CardId { get; private set; } // actual card data must be stored in a PCI compliant system, like Stripe
public string Last4 { get; private set; }
}
public string Alias { get; private set; }
public string CardId { get; private set; } // actual card data must be stored in a PCI compliant system, like Stripe
public string Last4 { get; private set; }
}

View File

@@ -1,13 +1,12 @@
using Microsoft.eShopWeb.ApplicationCore.Interfaces;
namespace Microsoft.eShopWeb.ApplicationCore.Entities
namespace Microsoft.eShopWeb.ApplicationCore.Entities;
public class CatalogBrand : BaseEntity, IAggregateRoot
{
public class CatalogBrand : BaseEntity, IAggregateRoot
public string Brand { get; private set; }
public CatalogBrand(string brand)
{
public string Brand { get; private set; }
public CatalogBrand(string brand)
{
Brand = brand;
}
Brand = brand;
}
}

View File

@@ -1,66 +1,65 @@
using Ardalis.GuardClauses;
using System;
using Ardalis.GuardClauses;
using Microsoft.eShopWeb.ApplicationCore.Interfaces;
using System;
namespace Microsoft.eShopWeb.ApplicationCore.Entities
namespace Microsoft.eShopWeb.ApplicationCore.Entities;
public class CatalogItem : BaseEntity, IAggregateRoot
{
public class CatalogItem : BaseEntity, IAggregateRoot
public string Name { get; private set; }
public string Description { get; private set; }
public decimal Price { get; private set; }
public string PictureUri { get; private set; }
public int CatalogTypeId { get; private set; }
public CatalogType CatalogType { get; private set; }
public int CatalogBrandId { get; private set; }
public CatalogBrand CatalogBrand { get; private set; }
public CatalogItem(int catalogTypeId,
int catalogBrandId,
string description,
string name,
decimal price,
string pictureUri)
{
public string Name { get; private set; }
public string Description { get; private set; }
public decimal Price { get; private set; }
public string PictureUri { get; private set; }
public int CatalogTypeId { get; private set; }
public CatalogType CatalogType { get; private set; }
public int CatalogBrandId { get; private set; }
public CatalogBrand CatalogBrand { get; private set; }
public CatalogItem(int catalogTypeId,
int catalogBrandId,
string description,
string name,
decimal price,
string pictureUri)
{
CatalogTypeId = catalogTypeId;
CatalogBrandId = catalogBrandId;
Description = description;
Name = name;
Price = price;
PictureUri = pictureUri;
}
public void UpdateDetails(string name, string description, decimal price)
{
Guard.Against.NullOrEmpty(name, nameof(name));
Guard.Against.NullOrEmpty(description, nameof(description));
Guard.Against.NegativeOrZero(price, nameof(price));
Name = name;
Description = description;
Price = price;
}
public void UpdateBrand(int catalogBrandId)
{
Guard.Against.Zero(catalogBrandId, nameof(catalogBrandId));
CatalogBrandId = catalogBrandId;
}
public void UpdateType(int catalogTypeId)
{
Guard.Against.Zero(catalogTypeId, nameof(catalogTypeId));
CatalogTypeId = catalogTypeId;
}
public void UpdatePictureUri(string pictureName)
{
if (string.IsNullOrEmpty(pictureName))
{
PictureUri = string.Empty;
return;
}
PictureUri = $"images\\products\\{pictureName}?{new DateTime().Ticks}";
}
CatalogTypeId = catalogTypeId;
CatalogBrandId = catalogBrandId;
Description = description;
Name = name;
Price = price;
PictureUri = pictureUri;
}
}
public void UpdateDetails(string name, string description, decimal price)
{
Guard.Against.NullOrEmpty(name, nameof(name));
Guard.Against.NullOrEmpty(description, nameof(description));
Guard.Against.NegativeOrZero(price, nameof(price));
Name = name;
Description = description;
Price = price;
}
public void UpdateBrand(int catalogBrandId)
{
Guard.Against.Zero(catalogBrandId, nameof(catalogBrandId));
CatalogBrandId = catalogBrandId;
}
public void UpdateType(int catalogTypeId)
{
Guard.Against.Zero(catalogTypeId, nameof(catalogTypeId));
CatalogTypeId = catalogTypeId;
}
public void UpdatePictureUri(string pictureName)
{
if (string.IsNullOrEmpty(pictureName))
{
PictureUri = string.Empty;
return;
}
PictureUri = $"images\\products\\{pictureName}?{new DateTime().Ticks}";
}
}

View File

@@ -1,13 +1,12 @@
using Microsoft.eShopWeb.ApplicationCore.Interfaces;
namespace Microsoft.eShopWeb.ApplicationCore.Entities
namespace Microsoft.eShopWeb.ApplicationCore.Entities;
public class CatalogType : BaseEntity, IAggregateRoot
{
public class CatalogType : BaseEntity, IAggregateRoot
public string Type { get; private set; }
public CatalogType(string type)
{
public string Type { get; private set; }
public CatalogType(string type)
{
Type = type;
}
Type = type;
}
}

View File

@@ -1,26 +1,25 @@
namespace Microsoft.eShopWeb.ApplicationCore.Entities.OrderAggregate
namespace Microsoft.eShopWeb.ApplicationCore.Entities.OrderAggregate;
public class Address // ValueObject
{
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)
{
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;
}
Street = street;
City = city;
State = state;
Country = country;
ZipCode = zipcode;
}
}

View File

@@ -1,31 +1,30 @@
using Ardalis.GuardClauses;
namespace Microsoft.eShopWeb.ApplicationCore.Entities.OrderAggregate
namespace Microsoft.eShopWeb.ApplicationCore.Entities.OrderAggregate;
/// <summary>
/// Represents a snapshot of 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
{
/// <summary>
/// Represents a snapshot of 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)
{
public CatalogItemOrdered(int catalogItemId, string productName, string pictureUri)
{
Guard.Against.OutOfRange(catalogItemId, nameof(catalogItemId), 1, int.MaxValue);
Guard.Against.NullOrEmpty(productName, nameof(productName));
Guard.Against.NullOrEmpty(pictureUri, nameof(pictureUri));
Guard.Against.OutOfRange(catalogItemId, nameof(catalogItemId), 1, int.MaxValue);
Guard.Against.NullOrEmpty(productName, nameof(productName));
Guard.Against.NullOrEmpty(pictureUri, nameof(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; }
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; }
}

View File

@@ -1,52 +1,51 @@
using Ardalis.GuardClauses;
using Microsoft.eShopWeb.ApplicationCore.Interfaces;
using System;
using System;
using System.Collections.Generic;
using Ardalis.GuardClauses;
using Microsoft.eShopWeb.ApplicationCore.Interfaces;
namespace Microsoft.eShopWeb.ApplicationCore.Entities.OrderAggregate
namespace Microsoft.eShopWeb.ApplicationCore.Entities.OrderAggregate;
public class Order : BaseEntity, IAggregateRoot
{
public class Order : BaseEntity, IAggregateRoot
private Order()
{
private Order()
// required by EF
}
public Order(string buyerId, Address shipToAddress, List<OrderItem> items)
{
Guard.Against.NullOrEmpty(buyerId, nameof(buyerId));
Guard.Against.Null(shipToAddress, nameof(shipToAddress));
Guard.Against.Null(items, nameof(items));
BuyerId = buyerId;
ShipToAddress = shipToAddress;
_orderItems = items;
}
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>();
// 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 IReadOnlyCollection<OrderItem> OrderItems => _orderItems.AsReadOnly();
public decimal Total()
{
var total = 0m;
foreach (var item in _orderItems)
{
// required by EF
}
public Order(string buyerId, Address shipToAddress, List<OrderItem> items)
{
Guard.Against.NullOrEmpty(buyerId, nameof(buyerId));
Guard.Against.Null(shipToAddress, nameof(shipToAddress));
Guard.Against.Null(items, nameof(items));
BuyerId = buyerId;
ShipToAddress = shipToAddress;
_orderItems = items;
}
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>();
// 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 IReadOnlyCollection<OrderItem> OrderItems => _orderItems.AsReadOnly();
public decimal Total()
{
var total = 0m;
foreach (var item in _orderItems)
{
total += item.UnitPrice * item.Units;
}
return total;
total += item.UnitPrice * item.Units;
}
return total;
}
}

View File

@@ -1,21 +1,20 @@
namespace Microsoft.eShopWeb.ApplicationCore.Entities.OrderAggregate
namespace Microsoft.eShopWeb.ApplicationCore.Entities.OrderAggregate;
public class OrderItem : BaseEntity
{
public class OrderItem : BaseEntity
public CatalogItemOrdered ItemOrdered { get; private set; }
public decimal UnitPrice { get; private set; }
public int Units { get; private set; }
private OrderItem()
{
public CatalogItemOrdered ItemOrdered { get; private set; }
public decimal UnitPrice { get; private set; }
public int Units { get; private set; }
// required by EF
}
private OrderItem()
{
// required by EF
}
public OrderItem(CatalogItemOrdered itemOrdered, decimal unitPrice, int units)
{
ItemOrdered = itemOrdered;
UnitPrice = unitPrice;
Units = units;
}
public OrderItem(CatalogItemOrdered itemOrdered, decimal unitPrice, int units)
{
ItemOrdered = itemOrdered;
UnitPrice = unitPrice;
Units = units;
}
}