Browse Source

Merge branch 'migration/net11'

# Conflicts:
#	docs/architecting-and-developing-containerized-and-microservice-based-net-applications-ebook-early-draft.pdf
#	src/Services/Ordering/Ordering.API/Startup.cs
pull/49/merge
etomas 8 years ago
parent
commit
decb87e0c6
43 changed files with 428 additions and 264 deletions
  1. +1
    -1
      eShopOnContainers-ServicesAndWebApps.sln
  2. +1
    -1
      src/Services/Basket/Basket.API/Controllers/BasketController.cs
  3. +1
    -1
      src/Services/Basket/Basket.API/Dockerfile
  4. +1
    -1
      src/Services/Basket/Basket.API/Model/RedisBasketRepository.cs
  5. +1
    -1
      src/Services/Basket/Basket.API/Startup.cs
  6. +16
    -15
      src/Services/Basket/Basket.API/project.json
  7. +15
    -15
      src/Services/Catalog/Catalog.API/Controllers/CatalogController.cs
  8. +1
    -1
      src/Services/Catalog/Catalog.API/Dockerfile
  9. +0
    -2
      src/Services/Catalog/Catalog.API/Startup.cs
  10. +32
    -32
      src/Services/Catalog/Catalog.API/project.json
  11. +2
    -2
      src/Services/Identity/Identity.API/Controllers/HomeController.cs
  12. +1
    -1
      src/Services/Identity/Identity.API/Dockerfile
  13. +29
    -33
      src/Services/Identity/Identity.API/project.json
  14. +1
    -1
      src/Services/Ordering/Ordering.API/Application/Commands/CreateOrderCommand.cs
  15. +12
    -4
      src/Services/Ordering/Ordering.API/Application/Commands/CreateOrderCommandHandler.cs
  16. +4
    -3
      src/Services/Ordering/Ordering.API/Application/Queries/OrderQueries.cs
  17. +5
    -5
      src/Services/Ordering/Ordering.API/Controllers/OrdersController.cs
  18. +11
    -1
      src/Services/Ordering/Ordering.API/Infrastructure/AutofacModules/ApplicationModule.cs
  19. +31
    -18
      src/Services/Ordering/Ordering.API/Infrastructure/Migrations/20170208181933_Initial.Designer.cs
  20. +41
    -9
      src/Services/Ordering/Ordering.API/Infrastructure/Migrations/20170208181933_Initial.cs
  21. +30
    -17
      src/Services/Ordering/Ordering.API/Infrastructure/Migrations/OrderingContextModelSnapshot.cs
  22. +1
    -2
      src/Services/Ordering/Ordering.API/Startup.cs
  23. +5
    -5
      src/Services/Ordering/Ordering.Domain/AggregatesModel/BuyerAggregate/Buyer.cs
  24. +1
    -1
      src/Services/Ordering/Ordering.Domain/AggregatesModel/BuyerAggregate/IBuyerRepository.cs
  25. +18
    -6
      src/Services/Ordering/Ordering.Domain/AggregatesModel/OrderAggregate/Address.cs
  26. +1
    -1
      src/Services/Ordering/Ordering.Domain/AggregatesModel/OrderAggregate/IOrderRepository.cs
  27. +25
    -18
      src/Services/Ordering/Ordering.Domain/AggregatesModel/OrderAggregate/Order.cs
  28. +7
    -5
      src/Services/Ordering/Ordering.Domain/AggregatesModel/OrderAggregate/OrderItem.cs
  29. +1
    -1
      src/Services/Ordering/Ordering.Domain/SeedWork/IAggregateRepository.cs
  30. +63
    -0
      src/Services/Ordering/Ordering.Domain/SeedWork/ValueObject.cs
  31. +15
    -8
      src/Services/Ordering/Ordering.Infrastructure/OrderingContext.cs
  32. +1
    -1
      src/Services/Ordering/Ordering.Infrastructure/Repositories/BuyerRepository.cs
  33. +1
    -1
      src/Web/WebMVC/Dockerfile
  34. +2
    -2
      src/Web/WebMVC/Services/BasketService.cs
  35. +2
    -2
      src/Web/WebMVC/Services/CatalogService.cs
  36. +2
    -2
      src/Web/WebMVC/Services/OrderingService.cs
  37. +1
    -1
      src/Web/WebMVC/Views/Order/Index.cshtml
  38. +20
    -19
      src/Web/WebMVC/project.json
  39. +1
    -1
      src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/orders/orders.component.html
  40. +1
    -1
      src/Web/WebSPA/eShopOnContainers.WebSPA/Dockerfile
  41. +2
    -2
      src/Web/WebSPA/eShopOnContainers.WebSPA/Server/Controllers/HomeController.cs
  42. +19
    -18
      src/Web/WebSPA/eShopOnContainers.WebSPA/project.json
  43. +3
    -3
      test/Services/UnitTest/Ordering/Application/NewOrderCommandHandlerTest.cs

+ 1
- 1
eShopOnContainers-ServicesAndWebApps.sln View File

@ -47,7 +47,7 @@ Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "UnitTest", "test\Services\U
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Identity", "Identity", "{24CD3B53-141E-4A07-9B0D-796641E1CF78}"
EndProject
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Identity.API", "src\Services\Identity\eShopOnContainers.Identity\Identity.API.xproj", "{A579E108-5445-403D-A407-339AC4D1611B}"
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Identity.API", "src\Services\Identity\Identity.API\Identity.API.xproj", "{A579E108-5445-403D-A407-339AC4D1611B}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution


+ 1
- 1
src/Services/Basket/Basket.API/Controllers/BasketController.cs View File

@ -8,7 +8,7 @@ using Microsoft.AspNetCore.Authorization;
namespace Microsoft.eShopOnContainers.Services.Basket.API.Controllers
{
//NOTE: Right now this is a very chunky API, as the app evolves it is possible we would
//TODO NOTE: Right now this is a very chunky API, as the app evolves it is possible we would
//want to make the actions more fine graned, add basket item as an action for example.
//If this is the case we should also investigate changing the serialization format used for Redis,
//using a HashSet instead of a simple string.


+ 1
- 1
src/Services/Basket/Basket.API/Dockerfile View File

@ -1,4 +1,4 @@
FROM microsoft/aspnetcore:1.0.1
FROM microsoft/aspnetcore:1.1
ENTRYPOINT ["dotnet", "Basket.API.dll"]
ARG source=.
WORKDIR /app


+ 1
- 1
src/Services/Basket/Basket.API/Model/RedisBasketRepository.cs View File

@ -18,7 +18,7 @@ namespace Microsoft.eShopOnContainers.Services.Basket.API.Model
private ConnectionMultiplexer _redis;
public RedisBasketRepository(IOptions<BasketSettings> options, ILoggerFactory loggerFactory)
public RedisBasketRepository(IOptionsSnapshot<BasketSettings> options, ILoggerFactory loggerFactory)
{
_settings = options.Value;
_logger = loggerFactory.CreateLogger<RedisBasketRepository>();


+ 1
- 1
src/Services/Basket/Basket.API/Startup.cs View File

@ -44,7 +44,7 @@ namespace Microsoft.eShopOnContainers.Services.Basket.API
//that cost to startup instead of having the first request pay the
//penalty.
services.AddSingleton<ConnectionMultiplexer>((sp) => {
var config = sp.GetRequiredService<IOptions<BasketSettings>>().Value;
var config = sp.GetRequiredService<IOptionsSnapshot<BasketSettings>>().Value;
var ips = Dns.GetHostAddressesAsync(config.ConnectionString).Result;
return ConnectionMultiplexer.Connect(ips.First().ToString());
});


+ 16
- 15
src/Services/Basket/Basket.API/project.json View File

@ -1,20 +1,20 @@
{
"dependencies": {
"Microsoft.NETCore.App": {
"version": "1.0.0",
"version": "1.1.0",
"type": "platform"
},
"System.Threading": "4.0.11",
"Microsoft.AspNetCore.Mvc": "1.0.0",
"Microsoft.AspNetCore.Server.IISIntegration": "1.0.0",
"Microsoft.AspNetCore.Server.Kestrel": "1.0.0",
"Microsoft.Extensions.Configuration.EnvironmentVariables": "1.0.0",
"Microsoft.Extensions.Configuration.FileExtensions": "1.0.0",
"Microsoft.Extensions.Configuration.Json": "1.0.0",
"Microsoft.Extensions.Logging": "1.0.0",
"Microsoft.Extensions.Logging.Console": "1.0.0",
"Microsoft.Extensions.Logging.Debug": "1.0.0",
"Microsoft.Extensions.Options.ConfigurationExtensions": "1.0.0",
"System.Threading": "4.3.0",
"Microsoft.AspNetCore.Mvc": "1.1.0",
"Microsoft.AspNetCore.Server.IISIntegration": "1.1.0",
"Microsoft.AspNetCore.Server.Kestrel": "1.1.0",
"Microsoft.Extensions.Configuration.EnvironmentVariables": "1.1.0",
"Microsoft.Extensions.Configuration.FileExtensions": "1.1.0",
"Microsoft.Extensions.Configuration.Json": "1.1.0",
"Microsoft.Extensions.Logging": "1.1.0",
"Microsoft.Extensions.Logging.Console": "1.1.0",
"Microsoft.Extensions.Logging.Debug": "1.1.0",
"Microsoft.Extensions.Options.ConfigurationExtensions": "1.1.0",
"StackExchange.Redis": "1.1.608",
"Newtonsoft.Json": "9.0.1",
"IdentityServer4.AccessTokenValidation": "1.0.1-rc3",
@ -24,10 +24,11 @@
"Microsoft.AspNetCore.Server.IISIntegration.Tools": "1.0.0-preview2-final"
},
"frameworks": {
"netcoreapp1.0": {
"netcoreapp1.1": {
"imports": [
"dotnet5.6",
"portable-net45+win8"
"netstandard1.6.1",
"dnxcore50",
"portable-net451+win8"
]
}
},


+ 15
- 15
src/Services/Catalog/Catalog.API/Controllers/CatalogController.cs View File

@ -1,27 +1,27 @@

using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Microsoft.eShopOnContainers.Services.Catalog.API.Infrastructure;
using Microsoft.eShopOnContainers.Services.Catalog.API.Model;
using Microsoft.eShopOnContainers.Services.Catalog.API.ViewModel;
using Microsoft.Extensions.Options;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Microsoft.eShopOnContainers.Services.Catalog.API.Controllers
{
using Extensions.Options;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Microsoft.eShopOnContainers.Services.Catalog.API.Infrastructure;
using Model;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using ViewModel;
[Route("api/v1/[controller]")]
public class CatalogController : ControllerBase
{
private readonly CatalogContext _context;
private readonly IOptions<Settings> _settings;
private readonly IOptionsSnapshot<Settings> _settings;
public CatalogController(CatalogContext context, IOptions<Settings> settings)
public CatalogController(CatalogContext context, IOptionsSnapshot<Settings> settings)
{
_context = context;
_settings = settings;
((DbContext)context).ChangeTracker.QueryTrackingBehavior = QueryTrackingBehavior.NoTracking;
}
// GET api/v1/[controller]/items/[?pageSize=3&pageIndex=10]
@ -30,7 +30,7 @@ namespace Microsoft.eShopOnContainers.Services.Catalog.API.Controllers
public async Task<IActionResult> Items(int pageSize = 10, int pageIndex = 0)
{
var totalItems = await _context.CatalogItems
.LongCountAsync();
.LongCountAsync();
var itemsOnPage = await _context.CatalogItems
.OrderBy(c=>c.Name)


+ 1
- 1
src/Services/Catalog/Catalog.API/Dockerfile View File

@ -1,4 +1,4 @@
FROM microsoft/aspnetcore:1.0.1
FROM microsoft/aspnetcore:1.1
WORKDIR /app
EXPOSE 80
COPY . /app

+ 0
- 2
src/Services/Catalog/Catalog.API/Startup.cs View File

@ -38,8 +38,6 @@
public void ConfigureServices(IServiceCollection services)
{
services.AddSingleton<IConfiguration>(Configuration);
services.AddDbContext<CatalogContext>(c =>
{
c.UseSqlServer(Configuration["ConnectionString"]);


+ 32
- 32
src/Services/Catalog/Catalog.API/project.json View File

@ -1,49 +1,41 @@
{
"buildOptions": {
"emitEntryPoint": true,
"preserveCompilationContext": true,
"debugType": "portable"
},
"dependencies": {
"Microsoft.NETCore.App": {
"version": "1.0.1",
"version": "1.1.0",
"type": "platform"
},
"Microsoft.AspNetCore.Mvc": "1.0.1",
"Microsoft.AspNetCore.Diagnostics": "1.0.0",
"Microsoft.AspNetCore.Diagnostics.Abstractions": "1.0.0",
"Microsoft.AspNetCore.Server.IISIntegration": "1.0.0",
"Microsoft.AspNetCore.Server.Kestrel": "1.0.1",
"Microsoft.Extensions.Configuration.EnvironmentVariables": "1.0.0",
"Microsoft.Extensions.Configuration.FileExtensions": "1.0.0",
"Microsoft.Extensions.Configuration.UserSecrets": "1.0.0",
"Microsoft.Extensions.Configuration.Json": "1.0.0",
"Microsoft.Extensions.Logging": "1.0.0",
"Microsoft.Extensions.Logging.Console": "1.0.0",
"Microsoft.Extensions.Logging.Debug": "1.0.0",
"Microsoft.Extensions.Options.ConfigurationExtensions": "1.0.0",
"Microsoft.EntityFrameworkCore": "1.0.1",
"Microsoft.EntityFrameworkCore.Relational": "1.0.1",
"Microsoft.EntityFrameworkCore.SqlServer": "1.0.1",
"Microsoft.EntityFrameworkCore.Design": "1.0.0-preview2-final",
"Microsoft.AspNetCore.Mvc": "1.1.0",
"Microsoft.AspNetCore.Diagnostics": "1.1.0",
"Microsoft.AspNetCore.Diagnostics.Abstractions": "1.1.0",
"Microsoft.AspNetCore.Server.IISIntegration": "1.1.0",
"Microsoft.AspNetCore.Server.Kestrel": "1.1.0",
"Microsoft.Extensions.Configuration.EnvironmentVariables": "1.1.0",
"Microsoft.Extensions.Configuration.FileExtensions": "1.1.0",
"Microsoft.Extensions.Configuration.UserSecrets": "1.1.0",
"Microsoft.Extensions.Configuration.Json": "1.1.0",
"Microsoft.Extensions.Logging": "1.1.0",
"Microsoft.Extensions.Logging.Console": "1.1.0",
"Microsoft.Extensions.Logging.Debug": "1.1.0",
"Microsoft.Extensions.Options.ConfigurationExtensions": "1.1.0",
"Microsoft.EntityFrameworkCore": "1.1.0",
"Microsoft.EntityFrameworkCore.Relational": "1.1.0",
"Microsoft.EntityFrameworkCore.SqlServer": "1.1.0",
"Microsoft.EntityFrameworkCore.Design": "1.1.0",
"Swashbuckle": "6.0.0-beta902"
},
"tools": {
"Microsoft.EntityFrameworkCore.Tools": "1.0.0-preview2-final"
},
"frameworks": {
"netcoreapp1.0": {
"netcoreapp1.1": {
"imports": [
"dotnet5.6",
"portable-net45+win8"
]
}
},
"buildOptions": {
"emitEntryPoint": true,
"preserveCompilationContext": true,
"debugType": "portable"
},
"runtimeOptions": {
"configProperties": {
"System.GC.Server": true
}
},
"publishOptions": {
"include": [
"wwwroot",
@ -56,6 +48,14 @@
"Dockerfile"
]
},
"runtimeOptions": {
"configProperties": {
"System.GC.Server": true
}
},
"scripts": {},
"tools": {
"Microsoft.EntityFrameworkCore.Tools": "1.1.0-preview4-final"
},
"userSecretsId": "aspnet-Catalog.API-20161122013618"
}

+ 2
- 2
src/Services/Identity/Identity.API/Controllers/HomeController.cs View File

@ -15,10 +15,10 @@ namespace IdentityServer4.Quickstart.UI.Controllers
public class HomeController : Controller
{
private readonly IIdentityServerInteractionService _interaction;
private readonly IOptions<AppSettings> _settings;
private readonly IOptionsSnapshot<AppSettings> _settings;
private readonly IRedirectService _redirectSvc;
public HomeController(IIdentityServerInteractionService interaction, IOptions<AppSettings> settings,IRedirectService redirectSvc)
public HomeController(IIdentityServerInteractionService interaction, IOptionsSnapshot<AppSettings> settings,IRedirectService redirectSvc)
{
_interaction = interaction;
_settings = settings;


+ 1
- 1
src/Services/Identity/Identity.API/Dockerfile View File

@ -1,4 +1,4 @@
FROM microsoft/aspnetcore:1.0.1
FROM microsoft/aspnetcore:1.1
ENTRYPOINT ["dotnet", "Identity.API.dll"]
ARG source=.
WORKDIR /app


+ 29
- 33
src/Services/Identity/Identity.API/project.json View File

@ -3,59 +3,55 @@
"dependencies": {
"Microsoft.NETCore.App": {
"version": "1.0.1",
"version": "1.1.0",
"type": "platform"
},
"Microsoft.AspNetCore.Authentication.Cookies": "1.0.0",
"Microsoft.AspNetCore.Diagnostics": "1.0.0",
"Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore": "1.0.0",
"Microsoft.AspNetCore.Identity.EntityFrameworkCore": "1.0.0",
"Microsoft.AspNetCore.Mvc": "1.0.1",
"Microsoft.AspNetCore.Razor.Tools": {
"version": "1.0.0-preview2-final",
"type": "build"
},
"Microsoft.AspNetCore.Routing": "1.0.1",
"Microsoft.AspNetCore.Server.IISIntegration": "1.0.0",
"Microsoft.AspNetCore.Server.Kestrel": "1.0.1",
"Microsoft.AspNetCore.StaticFiles": "1.0.0",
"Microsoft.EntityFrameworkCore.SqlServer": "1.0.1",
"Microsoft.AspNetCore.Authentication.Cookies": "1.1.0",
"Microsoft.AspNetCore.Diagnostics": "1.1.0",
"Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore": "1.1.0",
"Microsoft.AspNetCore.Identity.EntityFrameworkCore": "1.1.0",
"Microsoft.AspNetCore.Mvc": "1.1.0",
"Microsoft.AspNetCore.Routing": "1.1.0",
"Microsoft.AspNetCore.Server.IISIntegration": "1.1.0",
"Microsoft.AspNetCore.Server.Kestrel": "1.1.0",
"Microsoft.AspNetCore.StaticFiles": "1.1.0",
"Microsoft.EntityFrameworkCore.SqlServer": "1.1.0",
"Microsoft.EntityFrameworkCore.SqlServer.Design": {
"version": "1.0.1",
"version": "1.1.0",
"type": "build"
},
"Microsoft.EntityFrameworkCore.Tools": {
"version": "1.0.0-preview2-final",
"version": "1.1.0-preview4-final",
"type": "build"
},
"Microsoft.Extensions.Configuration.EnvironmentVariables": "1.0.0",
"Microsoft.Extensions.Configuration.Json": "1.0.0",
"Microsoft.Extensions.Configuration.UserSecrets": "1.0.0",
"Microsoft.Extensions.Logging": "1.0.0",
"Microsoft.Extensions.Logging.Console": "1.0.0",
"Microsoft.Extensions.Logging.Debug": "1.0.0",
"Microsoft.Extensions.Options.ConfigurationExtensions": "1.0.0",
"Microsoft.VisualStudio.Web.BrowserLink.Loader": "14.0.0",
"Microsoft.Extensions.Configuration.EnvironmentVariables": "1.1.0",
"Microsoft.Extensions.Configuration.Json": "1.1.0",
"Microsoft.Extensions.Configuration.UserSecrets": "1.1.0",
"Microsoft.Extensions.Logging": "1.1.0",
"Microsoft.Extensions.Logging.Console": "1.1.0",
"Microsoft.Extensions.Logging.Debug": "1.1.0",
"Microsoft.Extensions.Options.ConfigurationExtensions": "1.1.0",
"Microsoft.VisualStudio.Web.BrowserLink.Loader": "14.1.0",
"Microsoft.VisualStudio.Web.CodeGeneration.Tools": {
"version": "1.0.0-preview2-final",
"version": "1.1.0-preview4-final",
"type": "build"
},
"Microsoft.VisualStudio.Web.CodeGenerators.Mvc": {
"version": "1.0.0-preview2-final",
"version": "1.1.0-preview4-final",
"type": "build"
},
"IdentityServer4.AspNetIdentity": "1.0.0-rc3",
"IdentityServer4.EntityFramework": "1.0.0-rc3"
"IdentityServer4.EntityFramework": "1.0.0-rc3",
},
"tools": {
"BundlerMinifier.Core": "2.0.238",
"Microsoft.AspNetCore.Razor.Tools": "1.0.0-preview2-final",
"Microsoft.AspNetCore.Server.IISIntegration.Tools": "1.0.0-preview2-final",
"Microsoft.EntityFrameworkCore.Tools": "1.0.0-preview2-final",
"Microsoft.Extensions.SecretManager.Tools": "1.0.0-preview2-final",
"Microsoft.AspNetCore.Razor.Tools": "1.1.0-preview4-final",
"Microsoft.AspNetCore.Server.IISIntegration.Tools": "1.1.0-preview4-final",
"Microsoft.EntityFrameworkCore.Tools": "1.1.0-preview4-final",
"Microsoft.Extensions.SecretManager.Tools": "1.1.0-preview4-final",
"Microsoft.VisualStudio.Web.CodeGeneration.Tools": {
"version": "1.0.0-preview2-final",
"version": "1.1.0-preview4-final",
"imports": [
"portable-net45+win8"
]


+ 1
- 1
src/Services/Ordering/Ordering.API/Application/Commands/CreateOrderCommand.cs View File

@ -31,7 +31,7 @@ namespace Microsoft.eShopOnContainers.Services.Ordering.API.Application.Commands
public int CardTypeId { get; set; }
public string BuyerFullName { get; set; }
public string BuyerIdentityGuid { get; set; }
public IEnumerable<OrderItemDTO> OrderItems => _orderItems;


+ 12
- 4
src/Services/Ordering/Ordering.API/Application/Commands/CreateOrderCommandHandler.cs View File

@ -12,6 +12,7 @@
private readonly IBuyerRepository _buyerRepository;
private readonly IOrderRepository _orderRepository;
// Using DI to inject infrastructure persistence Repositories
public CreateOrderCommandHandler(IBuyerRepository buyerRepository, IOrderRepository orderRepository)
{
if (buyerRepository == null)
@ -30,13 +31,16 @@
public async Task<bool> Handle(CreateOrderCommand message)
{
//find buyer/payment or add a new one buyer/payment
// Add/Update the Buyer AggregateRoot
// DDD patterns comment: Add child entities and value-objects through the Order Aggregate-Root
// methods and constructor so validations, invariants and business logic
// make sure that consistency is preserved across the whole aggregate
var buyer = await _buyerRepository.FindAsync(message.BuyerFullName);
var buyer = await _buyerRepository.FindAsync(message.BuyerIdentityGuid);
if (buyer == null)
{
buyer = new Buyer(message.BuyerFullName);
buyer = new Buyer(message.BuyerIdentityGuid);
}
var payment = buyer.AddPaymentMethod(message.CardTypeId,
@ -51,7 +55,10 @@
await _buyerRepository.UnitOfWork
.SaveChangesAsync();
//create order for buyer and payment method
// Create the Order AggregateRoot
// DDD patterns comment: Add child entities and value-objects through the Order Aggregate-Root
// methods and constructor so validations, invariants and business logic
// make sure that consistency is preserved across the whole aggregate
var order = new Order(buyer.Id, payment.Id, new Address(message.Street, message.City, message.State, message.Country, message.ZipCode));
@ -66,6 +73,7 @@
.SaveChangesAsync();
return result > 0;
}
}
}

+ 4
- 3
src/Services/Ordering/Ordering.API/Application/Queries/OrderQueries.cs View File

@ -13,9 +13,9 @@
{
private string _connectionString = string.Empty;
public OrderQueries(IConfiguration configuration)
public OrderQueries(string constr)
{
_connectionString = configuration["ConnectionString"];
_connectionString = constr;
}
@ -28,8 +28,9 @@
var result = await connection.QueryAsync<dynamic>(
@"select o.[Id] as ordernumber,o.OrderDate as date, os.Name as status,
oi.ProductName as productname, oi.Units as units, oi.UnitPrice as unitprice, oi.PictureUrl as pictureurl,
o.Street as street, o.City as city, o.Country as country, o.State as state, o.ZipCode as zipcode
a.Street as street, a.City as city, a.Country as country, a.State as state, a.ZipCode as zipcode
FROM ordering.Orders o
INNER JOIN ordering.Address a ON o.AddressId = a.Id
LEFT JOIN ordering.Orderitems oi ON o.Id = oi.orderid
LEFT JOIN ordering.orderstatus os on o.OrderStatusId = os.Id
WHERE o.Id=@id"


+ 5
- 5
src/Services/Ordering/Ordering.API/Controllers/OrdersController.cs View File

@ -11,7 +11,7 @@ using System.Threading.Tasks;
namespace Microsoft.eShopOnContainers.Services.Ordering.API.Controllers
{
[Route("api/v1/[controller]")]
[Authorize]
//[Authorize]
public class OrdersController : Controller
{
private readonly IMediator _mediator;
@ -42,17 +42,17 @@ namespace Microsoft.eShopOnContainers.Services.Ordering.API.Controllers
[Route("new")]
[HttpPost]
public async Task<IActionResult> AddOrder([FromBody]CreateOrderCommand createOrderCommand)
public async Task<IActionResult> CreateOrder([FromBody]CreateOrderCommand createOrderCommand)
{
if (createOrderCommand.CardTypeId == 0)
{
createOrderCommand.CardTypeId = 1;
}
createOrderCommand.BuyerFullName = _identityService.GetUserIdentity();
createOrderCommand.BuyerIdentityGuid = _identityService.GetUserIdentity();
var added = await _mediator.SendAsync(createOrderCommand);
if (added)
var result = await _mediator.SendAsync(createOrderCommand);
if (result)
{
return Ok();
}


+ 11
- 1
src/Services/Ordering/Ordering.API/Infrastructure/AutofacModules/ApplicationModule.cs View File

@ -10,9 +10,19 @@ namespace Microsoft.eShopOnContainers.Services.Ordering.API.Infrastructure.Autof
public class ApplicationModule
:Autofac.Module
{
public string QueriesConnectionString { get; }
public ApplicationModule(string qconstr)
{
QueriesConnectionString = qconstr;
}
protected override void Load(ContainerBuilder builder)
{
builder.RegisterType<OrderQueries>()
builder.Register(c => new OrderQueries(QueriesConnectionString))
.As<IOrderQueries>()
.InstancePerLifetimeScope();


src/Services/Ordering/Ordering.API/Infrastructure/Migrations/20170127103457_Initial.Designer.cs → src/Services/Ordering/Ordering.API/Infrastructure/Migrations/20170208181933_Initial.Designer.cs View File

@ -8,7 +8,7 @@ using Microsoft.eShopOnContainers.Services.Ordering.Infrastructure;
namespace Ordering.API.Migrations
{
[DbContext(typeof(OrderingContext))]
[Migration("20170127103457_Initial")]
[Migration("20170208181933_Initial")]
partial class Initial
{
protected override void BuildTargetModel(ModelBuilder modelBuilder)
@ -29,13 +29,13 @@ namespace Ordering.API.Migrations
.HasAnnotation("SqlServer:HiLoSequenceSchema", "ordering")
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.SequenceHiLo);
b.Property<string>("FullName")
b.Property<string>("IdentityGuid")
.IsRequired()
.HasMaxLength(200);
b.HasKey("Id");
b.HasIndex("FullName")
b.HasIndex("IdentityGuid")
.IsUnique();
b.ToTable("buyers","ordering");
@ -90,6 +90,26 @@ namespace Ordering.API.Migrations
b.ToTable("paymentmethods","ordering");
});
modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate.Address", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd();
b.Property<string>("City");
b.Property<string>("Country");
b.Property<string>("State");
b.Property<string>("Street");
b.Property<string>("ZipCode");
b.HasKey("Id");
b.ToTable("address","ordering");
});
modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate.Order", b =>
{
b.Property<int>("Id")
@ -98,13 +118,9 @@ namespace Ordering.API.Migrations
.HasAnnotation("SqlServer:HiLoSequenceSchema", "ordering")
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.SequenceHiLo);
b.Property<int>("BuyerId");
b.Property<string>("City")
.IsRequired();
b.Property<int?>("AddressId");
b.Property<string>("Country")
.IsRequired();
b.Property<int>("BuyerId");
b.Property<DateTime>("OrderDate");
@ -112,17 +128,10 @@ namespace Ordering.API.Migrations
b.Property<int>("PaymentMethodId");
b.Property<string>("State")
.IsRequired();
b.Property<string>("Street")
.IsRequired();
b.Property<string>("ZipCode")
.IsRequired();
b.HasKey("Id");
b.HasIndex("AddressId");
b.HasIndex("BuyerId");
b.HasIndex("OrderStatusId");
@ -190,6 +199,10 @@ namespace Ordering.API.Migrations
modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate.Order", b =>
{
b.HasOne("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate.Address", "Address")
.WithMany()
.HasForeignKey("AddressId");
b.HasOne("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.BuyerAggregate.Buyer", "Buyer")
.WithMany()
.HasForeignKey("BuyerId")

src/Services/Ordering/Ordering.API/Infrastructure/Migrations/20170127103457_Initial.cs → src/Services/Ordering/Ordering.API/Infrastructure/Migrations/20170208181933_Initial.cs View File

@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Metadata;
namespace Ordering.API.Migrations
{
@ -36,7 +37,7 @@ namespace Ordering.API.Migrations
columns: table => new
{
Id = table.Column<int>(nullable: false),
FullName = table.Column<string>(maxLength: 200, nullable: false)
IdentityGuid = table.Column<string>(maxLength: 200, nullable: false)
},
constraints: table =>
{
@ -56,6 +57,24 @@ namespace Ordering.API.Migrations
table.PrimaryKey("PK_cardtypes", x => x.Id);
});
migrationBuilder.CreateTable(
name: "address",
schema: "ordering",
columns: table => new
{
Id = table.Column<int>(nullable: false)
.Annotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn),
City = table.Column<string>(nullable: true),
Country = table.Column<string>(nullable: true),
State = table.Column<string>(nullable: true),
Street = table.Column<string>(nullable: true),
ZipCode = table.Column<string>(nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_address", x => x.Id);
});
migrationBuilder.CreateTable(
name: "orderstatus",
schema: "ordering",
@ -107,19 +126,22 @@ namespace Ordering.API.Migrations
columns: table => new
{
Id = table.Column<int>(nullable: false),
AddressId = table.Column<int>(nullable: true),
BuyerId = table.Column<int>(nullable: false),
City = table.Column<string>(nullable: false),
Country = table.Column<string>(nullable: false),
OrderDate = table.Column<DateTime>(nullable: false),
OrderStatusId = table.Column<int>(nullable: false),
PaymentMethodId = table.Column<int>(nullable: false),
State = table.Column<string>(nullable: false),
Street = table.Column<string>(nullable: false),
ZipCode = table.Column<string>(nullable: false)
PaymentMethodId = table.Column<int>(nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_orders", x => x.Id);
table.ForeignKey(
name: "FK_orders_address_AddressId",
column: x => x.AddressId,
principalSchema: "ordering",
principalTable: "address",
principalColumn: "Id",
onDelete: ReferentialAction.Restrict);
table.ForeignKey(
name: "FK_orders_buyers_BuyerId",
column: x => x.BuyerId,
@ -170,10 +192,10 @@ namespace Ordering.API.Migrations
});
migrationBuilder.CreateIndex(
name: "IX_buyers_FullName",
name: "IX_buyers_IdentityGuid",
schema: "ordering",
table: "buyers",
column: "FullName",
column: "IdentityGuid",
unique: true);
migrationBuilder.CreateIndex(
@ -188,6 +210,12 @@ namespace Ordering.API.Migrations
table: "paymentmethods",
column: "CardTypeId");
migrationBuilder.CreateIndex(
name: "IX_orders_AddressId",
schema: "ordering",
table: "orders",
column: "AddressId");
migrationBuilder.CreateIndex(
name: "IX_orders_BuyerId",
schema: "ordering",
@ -223,6 +251,10 @@ namespace Ordering.API.Migrations
name: "orders",
schema: "ordering");
migrationBuilder.DropTable(
name: "address",
schema: "ordering");
migrationBuilder.DropTable(
name: "orderstatus",
schema: "ordering");

+ 30
- 17
src/Services/Ordering/Ordering.API/Infrastructure/Migrations/OrderingContextModelSnapshot.cs View File

@ -28,13 +28,13 @@ namespace Ordering.API.Migrations
.HasAnnotation("SqlServer:HiLoSequenceSchema", "ordering")
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.SequenceHiLo);
b.Property<string>("FullName")
b.Property<string>("IdentityGuid")
.IsRequired()
.HasMaxLength(200);
b.HasKey("Id");
b.HasIndex("FullName")
b.HasIndex("IdentityGuid")
.IsUnique();
b.ToTable("buyers","ordering");
@ -89,6 +89,26 @@ namespace Ordering.API.Migrations
b.ToTable("paymentmethods","ordering");
});
modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate.Address", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd();
b.Property<string>("City");
b.Property<string>("Country");
b.Property<string>("State");
b.Property<string>("Street");
b.Property<string>("ZipCode");
b.HasKey("Id");
b.ToTable("address","ordering");
});
modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate.Order", b =>
{
b.Property<int>("Id")
@ -97,13 +117,9 @@ namespace Ordering.API.Migrations
.HasAnnotation("SqlServer:HiLoSequenceSchema", "ordering")
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.SequenceHiLo);
b.Property<int>("BuyerId");
b.Property<string>("City")
.IsRequired();
b.Property<int?>("AddressId");
b.Property<string>("Country")
.IsRequired();
b.Property<int>("BuyerId");
b.Property<DateTime>("OrderDate");
@ -111,17 +127,10 @@ namespace Ordering.API.Migrations
b.Property<int>("PaymentMethodId");
b.Property<string>("State")
.IsRequired();
b.Property<string>("Street")
.IsRequired();
b.Property<string>("ZipCode")
.IsRequired();
b.HasKey("Id");
b.HasIndex("AddressId");
b.HasIndex("BuyerId");
b.HasIndex("OrderStatusId");
@ -189,6 +198,10 @@ namespace Ordering.API.Migrations
modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate.Order", b =>
{
b.HasOne("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate.Address", "Address")
.WithMany()
.HasForeignKey("AddressId");
b.HasOne("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.BuyerAggregate.Buyer", "Buyer")
.WithMany()
.HasForeignKey("BuyerId")


+ 1
- 2
src/Services/Ordering/Ordering.API/Startup.cs View File

@ -81,7 +81,6 @@
// Add application services.
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
services.AddSingleton<IConfiguration>(this.Configuration);
services.AddTransient<IIdentityService,IdentityService>();
services.AddOptions();
@ -92,7 +91,7 @@
container.Populate(services);
container.RegisterModule(new MediatorModule());
container.RegisterModule(new ApplicationModule());
container.RegisterModule(new ApplicationModule(Configuration["ConnectionString"] ));
return new AutofacServiceProvider(container.Build());
}


+ 5
- 5
src/Services/Ordering/Ordering.Domain/AggregatesModel/BuyerAggregate/Buyer.cs View File

@ -8,11 +8,11 @@ namespace Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.B
public class Buyer
: Entity, IAggregateRoot
{
public string FullName { get; private set; }
public string IdentityGuid { get; private set; }
private HashSet<PaymentMethod> _paymentMethods;
private List<PaymentMethod> _paymentMethods;
public IEnumerable<PaymentMethod> PaymentMethods => _paymentMethods?.ToList().AsEnumerable();
public IEnumerable<PaymentMethod> PaymentMethods => _paymentMethods?.AsReadOnly();
protected Buyer() { }
@ -23,9 +23,9 @@ namespace Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.B
throw new ArgumentNullException(nameof(identity));
}
FullName = identity;
IdentityGuid = identity;
_paymentMethods = new HashSet<PaymentMethod>();
_paymentMethods = new List<PaymentMethod>();
}
public PaymentMethod AddPaymentMethod(int cardTypeId, string alias, string cardNumber, string securityNumber, string cardHolderName, DateTime expiration)


+ 1
- 1
src/Services/Ordering/Ordering.Domain/AggregatesModel/BuyerAggregate/IBuyerRepository.cs View File

@ -7,7 +7,7 @@ namespace Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.B
//This is just the RepositoryContracts or Interface defined at the Domain Layer
//as requisite for the Buyer Aggregate
public interface IBuyerRepository
:IRepository
:IAggregateRepository
{
Buyer Add(Buyer buyer);


+ 18
- 6
src/Services/Ordering/Ordering.Domain/AggregatesModel/OrderAggregate/Address.cs View File

@ -1,18 +1,21 @@
using System;
using Microsoft.eShopOnContainers.Services.Ordering.Domain.SeedWork;
using System;
using System.Collections.Generic;
namespace Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate
{
public class Address
:ValueObject
{
public String Street { get; }
public String Street { get; private set; }
public String City { get; }
public String City { get; private set; }
public String State { get; }
public String State { get; private set; }
public String Country { get; }
public String Country { get; private set; }
public String ZipCode { get; }
public String ZipCode { get; private set; }
public Address(string street, string city, string state, string country, string zipcode)
{
@ -22,5 +25,14 @@ namespace Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.O
Country = country;
ZipCode = zipcode;
}
protected override IEnumerable<object> GetAtomicValues()
{
yield return Street;
yield return City;
yield return State;
yield return Country;
yield return ZipCode;
}
}
}

+ 1
- 1
src/Services/Ordering/Ordering.Domain/AggregatesModel/OrderAggregate/IOrderRepository.cs View File

@ -5,7 +5,7 @@ namespace Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.O
//This is just the RepositoryContracts or Interface defined at the Domain Layer
//as requisite for the Order Aggregate
public interface IOrderRepository
:IRepository
:IAggregateRepository
{
Order Add(Order order);
}


+ 25
- 18
src/Services/Ordering/Ordering.Domain/AggregatesModel/OrderAggregate/Order.cs View File

@ -9,44 +9,51 @@ namespace Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.O
public class Order
: Entity
{
private string _street;
private string _city;
private string _state;
private string _country;
private string _zipCode;
// DDD Patterns comment
// Using private fields, allowed since EF Core 1.1, is a much better encapsulation
// aligned with DDD Aggregates and Domain Entities (Instead of properties and property collections)
private DateTime _orderDate;
public Address Address { get; private set; }
public Buyer Buyer { get; private set; }
int _buyerId;
private int _buyerId;
public OrderStatus OrderStatus { get; private set; }
int _orderStatusId;
private int _orderStatusId;
// 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 OrderAggrergateRoot.AddOrderItem() which includes behaviour.
private readonly List<OrderItem> _orderItems;
HashSet<OrderItem> _orderItems;
public IEnumerable<OrderItem> OrderItems => _orderItems.ToList().AsEnumerable();
public IEnumerable<OrderItem> OrderItems => _orderItems.AsReadOnly();
// 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 PaymentMethod PaymentMethod { get; private set; }
int _paymentMethodId;
private int _paymentMethodId;
protected Order() { }
public Order(int buyerId, int paymentMethodId, Address address)
{
_orderItems = new List<OrderItem>();
_buyerId = buyerId;
_paymentMethodId = paymentMethodId;
_orderStatusId = OrderStatus.InProcess.Id;
_orderDate = DateTime.UtcNow;
_street = address.Street;
_city = address.City;
_state = address.State;
_country = address.Country;
_zipCode = address.ZipCode;
_orderItems = new HashSet<OrderItem>();
Address = address;
}
// DDD Patterns comment
// This Order AggregateRoot's method "AddOrderitem()" should be the only way to add Items to the Order,
// so any behavior (discounts, etc.) and validations are controlled by the AggregateRoot
// in order to maintain consistency between the whole Aggregate.
public void AddOrderItem(int productId, string productName, decimal unitPrice, decimal discount, string pictureUrl, int units = 1)
{
var existingOrderForProduct = _orderItems.Where(o => o.ProductId == productId)


+ 7
- 5
src/Services/Ordering/Ordering.Domain/AggregatesModel/OrderAggregate/OrderItem.cs View File

@ -6,16 +6,18 @@ namespace Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.O
public class OrderItem
: Entity
{
private string _productName;
private string _pictureUrl;
private int _orderId;
// DDD Patterns comment
// Using private fields, allowed since EF Core 1.1, is a much better encapsulation
// aligned with DDD Aggregates and Domain Entities (Instead of properties and property collections)
private string _productName;
private string _pictureUrl;
private int _orderId;
private decimal _unitPrice;
private decimal _discount;
private int _units;
private int _units;
public int ProductId { get; private set; }
protected OrderItem() { }
public OrderItem(int productId, string productName, decimal unitPrice, decimal discount, string PictureUrl, int units = 1)


src/Services/Ordering/Ordering.Domain/SeedWork/IRepository.cs → src/Services/Ordering/Ordering.Domain/SeedWork/IAggregateRepository.cs View File

@ -1,6 +1,6 @@
namespace Microsoft.eShopOnContainers.Services.Ordering.Domain.Seedwork
{
public interface IRepository
public interface IAggregateRepository
{
IUnitOfWork UnitOfWork { get; }
}

+ 63
- 0
src/Services/Ordering/Ordering.Domain/SeedWork/ValueObject.cs View File

@ -0,0 +1,63 @@
using System.Collections.Generic;
using System.Linq;
namespace Microsoft.eShopOnContainers.Services.Ordering.Domain.SeedWork
{
public abstract class ValueObject
{
protected static bool EqualOperator(ValueObject left, ValueObject right)
{
if (ReferenceEquals(left, null) ^ ReferenceEquals(right, null))
{
return false;
}
return ReferenceEquals(left, null) || left.Equals(right);
}
protected static bool NotEqualOperator(ValueObject left, ValueObject right)
{
return !(EqualOperator(left, right));
}
protected abstract IEnumerable<object> GetAtomicValues();
public override bool Equals(object obj)
{
if (obj == null || obj.GetType() != GetType())
{
return false;
}
ValueObject other = (ValueObject)obj;
IEnumerator<object> thisValues = GetAtomicValues().GetEnumerator();
IEnumerator<object> otherValues = other.GetAtomicValues().GetEnumerator();
while (thisValues.MoveNext() && otherValues.MoveNext())
{
if (ReferenceEquals(thisValues.Current, null) ^ ReferenceEquals(otherValues.Current, null))
{
return false;
}
if (thisValues.Current != null && !thisValues.Current.Equals(otherValues.Current))
{
return false;
}
}
return !thisValues.MoveNext() && !otherValues.MoveNext();
}
public override int GetHashCode()
{
return GetAtomicValues()
.Select(x => x != null ? x.GetHashCode() : 0)
.Aggregate((x, y) => x ^ y);
}
public ValueObject GetCopy()
{
return this.MemberwiseClone() as ValueObject;
}
}
}

+ 15
- 8
src/Services/Ordering/Ordering.Infrastructure/OrderingContext.cs View File

@ -30,6 +30,7 @@ namespace Microsoft.eShopOnContainers.Services.Ordering.Infrastructure
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Address>(ConfigureAddress);
modelBuilder.Entity<Buyer>(ConfigureBuyer);
modelBuilder.Entity<PaymentMethod>(ConfigurePayment);
modelBuilder.Entity<Order>(ConfigureOrder);
@ -38,6 +39,16 @@ namespace Microsoft.eShopOnContainers.Services.Ordering.Infrastructure
modelBuilder.Entity<OrderStatus>(ConfigureOrderStatus);
}
void ConfigureAddress(EntityTypeBuilder<Address> addressConfiguration)
{
addressConfiguration.ToTable("address", DEFAULT_SCHEMA);
addressConfiguration.Property<int>("Id")
.IsRequired();
addressConfiguration.HasKey("Id");
}
void ConfigureBuyer(EntityTypeBuilder<Buyer> buyerConfiguration)
{
buyerConfiguration.ToTable("buyers", DEFAULT_SCHEMA);
@ -47,11 +58,11 @@ namespace Microsoft.eShopOnContainers.Services.Ordering.Infrastructure
buyerConfiguration.Property(b => b.Id)
.ForSqlServerUseSequenceHiLo("buyerseq", DEFAULT_SCHEMA);
buyerConfiguration.Property(b=>b.FullName)
buyerConfiguration.Property(b=>b.IdentityGuid)
.HasMaxLength(200)
.IsRequired();
buyerConfiguration.HasIndex("FullName")
buyerConfiguration.HasIndex("IdentityGuid")
.IsUnique(true);
buyerConfiguration.HasMany(b => b.PaymentMethods)
@ -109,17 +120,13 @@ namespace Microsoft.eShopOnContainers.Services.Ordering.Infrastructure
.ForSqlServerUseSequenceHiLo("orderseq", DEFAULT_SCHEMA);
orderConfiguration.Property<DateTime>("OrderDate").IsRequired();
orderConfiguration.Property<string>("Street").IsRequired();
orderConfiguration.Property<string>("State").IsRequired();
orderConfiguration.Property<string>("City").IsRequired();
orderConfiguration.Property<string>("ZipCode").IsRequired();
orderConfiguration.Property<string>("Country").IsRequired();
orderConfiguration.Property<int>("BuyerId").IsRequired();
orderConfiguration.Property<int>("OrderStatusId").IsRequired();
orderConfiguration.Property<int>("PaymentMethodId").IsRequired();
var navigation = orderConfiguration.Metadata.FindNavigation(nameof(Order.OrderItems));
// DDD Patterns comment:
//Set as Field (New since EF 1.1) to access the OrderItem collection property through its field
navigation.SetPropertyAccessMode(PropertyAccessMode.Field);
orderConfiguration.HasOne(o => o.PaymentMethod)


+ 1
- 1
src/Services/Ordering/Ordering.Infrastructure/Repositories/BuyerRepository.cs View File

@ -49,7 +49,7 @@ namespace Microsoft.eShopOnContainers.Services.Ordering.Infrastructure.Repositor
{
var buyer = await _context.Buyers
.Include(b => b.PaymentMethods)
.Where(b => b.FullName == identity)
.Where(b => b.IdentityGuid == identity)
.SingleOrDefaultAsync();
return buyer;


+ 1
- 1
src/Web/WebMVC/Dockerfile View File

@ -1,4 +1,4 @@
FROM microsoft/aspnetcore:1.0.1
FROM microsoft/aspnetcore:1.1
ENTRYPOINT ["dotnet", "WebMVC.dll"]
ARG source=.
WORKDIR /app


+ 2
- 2
src/Web/WebMVC/Services/BasketService.cs View File

@ -14,12 +14,12 @@ namespace Microsoft.eShopOnContainers.WebMVC.Services
{
public class BasketService : IBasketService
{
private readonly IOptions<AppSettings> _settings;
private readonly IOptionsSnapshot<AppSettings> _settings;
private HttpClient _apiClient;
private readonly string _remoteServiceBaseUrl;
private IHttpContextAccessor _httpContextAccesor;
public BasketService(IOptions<AppSettings> settings, IHttpContextAccessor httpContextAccesor)
public BasketService(IOptionsSnapshot<AppSettings> settings, IHttpContextAccessor httpContextAccesor)
{
_settings = settings;
_remoteServiceBaseUrl = _settings.Value.BasketUrl;


+ 2
- 2
src/Web/WebMVC/Services/CatalogService.cs View File

@ -15,11 +15,11 @@ namespace Microsoft.eShopOnContainers.WebMVC.Services
{
public class CatalogService : ICatalogService
{
private readonly IOptions<AppSettings> _settings;
private readonly IOptionsSnapshot<AppSettings> _settings;
private HttpClient _apiClient;
private readonly string _remoteServiceBaseUrl;
public CatalogService(IOptions<AppSettings> settings, ILoggerFactory loggerFactory) {
public CatalogService(IOptionsSnapshot<AppSettings> settings, ILoggerFactory loggerFactory) {
_settings = settings;
_remoteServiceBaseUrl = $"{_settings.Value.CatalogUrl}/api/v1/catalog/";


+ 2
- 2
src/Web/WebMVC/Services/OrderingService.cs View File

@ -15,10 +15,10 @@ namespace Microsoft.eShopOnContainers.WebMVC.Services
{
private HttpClient _apiClient;
private readonly string _remoteServiceBaseUrl;
private readonly IOptions<AppSettings> _settings;
private readonly IOptionsSnapshot<AppSettings> _settings;
private readonly IHttpContextAccessor _httpContextAccesor;
public OrderingService(IOptions<AppSettings> settings, IHttpContextAccessor httpContextAccesor)
public OrderingService(IOptionsSnapshot<AppSettings> settings, IHttpContextAccessor httpContextAccesor)
{
_remoteServiceBaseUrl = $"{settings.Value.OrderingUrl}/api/v1/orders";
_settings = settings;


+ 1
- 1
src/Web/WebMVC/Views/Order/Index.cshtml View File

@ -25,7 +25,7 @@
<section class="esh-orders-item col-xs-4">@Html.DisplayFor(modelItem => item.Date)</section>
<section class="esh-orders-item col-xs-2">$ @Html.DisplayFor(modelItem => item.Total)</section>
<section class="esh-orders-item col-xs-2">@Html.DisplayFor(modelItem => item.Status)</section>
<section class="esh-orders-item esh-orders-item--hover col-xs-2">
<section class="esh-orders-item col-xs-2">
<a class="esh-orders-link" asp-controller="Order" asp-action="Detail" asp-route-orderId="@item.OrderNumber">Detail</a>
</section>
</article>


+ 20
- 19
src/Web/WebMVC/project.json View File

@ -2,27 +2,27 @@
"userSecretsId": "aspnet-Microsoft.eShopOnContainers-946ae052-8305-4a99-965b-ec8636ddbae3",
"dependencies": {
"Microsoft.NETCore.App": {
"version": "1.0.0",
"version": "1.1.0",
"type": "platform"
},
"Microsoft.AspNetCore.Authentication.Cookies": "1.0.0",
"Microsoft.AspNetCore.Diagnostics": "1.0.0",
"Microsoft.AspNetCore.Mvc": "1.0.0",
"Microsoft.AspNetCore.Authentication.Cookies": "1.1.0",
"Microsoft.AspNetCore.Diagnostics": "1.1.0",
"Microsoft.AspNetCore.Mvc": "1.1.1",
"Microsoft.AspNetCore.Razor.Tools": {
"version": "1.0.0-preview2-final",
"type": "build"
},
"Microsoft.AspNetCore.Server.IISIntegration": "1.0.0",
"Microsoft.AspNetCore.Server.Kestrel": "1.0.0",
"Microsoft.AspNetCore.StaticFiles": "1.0.0",
"Microsoft.Extensions.Configuration.EnvironmentVariables": "1.0.0",
"Microsoft.Extensions.Configuration.Json": "1.0.0",
"Microsoft.Extensions.Configuration.UserSecrets": "1.0.0",
"Microsoft.Extensions.Logging": "1.0.0",
"Microsoft.Extensions.Logging.Console": "1.0.0",
"Microsoft.Extensions.Logging.Debug": "1.0.0",
"Microsoft.Extensions.Options.ConfigurationExtensions": "1.0.0",
"Microsoft.VisualStudio.Web.BrowserLink.Loader": "14.0.0",
"Microsoft.AspNetCore.Server.IISIntegration": "1.1.0",
"Microsoft.AspNetCore.Server.Kestrel": "1.1.0",
"Microsoft.AspNetCore.StaticFiles": "1.1.0",
"Microsoft.Extensions.Configuration.EnvironmentVariables": "1.1.0",
"Microsoft.Extensions.Configuration.Json": "1.1.0",
"Microsoft.Extensions.Configuration.UserSecrets": "1.1.0",
"Microsoft.Extensions.Logging": "1.1.0",
"Microsoft.Extensions.Logging.Console": "1.1.0",
"Microsoft.Extensions.Logging.Debug": "1.1.0",
"Microsoft.Extensions.Options.ConfigurationExtensions": "1.1.0",
"Microsoft.VisualStudio.Web.BrowserLink.Loader": "14.1.0",
"Microsoft.VisualStudio.Web.CodeGeneration.Tools": {
"version": "1.0.0-preview2-final",
"type": "build"
@ -32,10 +32,11 @@
"type": "build"
},
"Newtonsoft.Json": "9.0.1",
"System.IdentityModel.Tokens.Jwt": "5.0.0",
"Microsoft.AspNetCore.Authentication.OpenIdConnect": "1.0.0",
"Microsoft.AspNetCore.Authentication.JwtBearer": "1.0.0",
"Microsoft.AspNetCore.Identity.EntityFrameworkCore": "1.0.0"
"System.IdentityModel.Tokens.Jwt": "5.1.0",
"Microsoft.AspNetCore.Authentication.OpenIdConnect": "1.1.0",
"Microsoft.AspNetCore.Authentication.JwtBearer": "1.1.0",
"Microsoft.AspNetCore.Identity.EntityFrameworkCore": "1.1.0",
"Microsoft.Extensions.Options": "1.1.0"
},
"tools": {
"BundlerMinifier.Core": "2.0.238",


+ 1
- 1
src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/orders/orders.component.html View File

@ -16,7 +16,7 @@
<section class="esh-orders-item col-xs-4">{{order.date | date:'short'}}</section>
<section class="esh-orders-item col-xs-2">$ {{order.total}}</section>
<section class="esh-orders-item col-xs-2">{{order.status}}</section>
<section class="esh-orders-item esh-orders-item--hover col-xs-2">
<section class="esh-orders-item col-xs-2">
<a class="esh-orders-link" routerLink="/orders/{{order.ordernumber}}">Detail</a>
</section>
</article>


+ 1
- 1
src/Web/WebSPA/eShopOnContainers.WebSPA/Dockerfile View File

@ -1,4 +1,4 @@
FROM microsoft/aspnetcore:1.0.1
FROM microsoft/aspnetcore:1.1
ENTRYPOINT ["dotnet", "eShopOnContainers.WebSPA.dll"]
ARG source=.
WORKDIR /app


+ 2
- 2
src/Web/WebSPA/eShopOnContainers.WebSPA/Server/Controllers/HomeController.cs View File

@ -11,9 +11,9 @@ namespace eShopConContainers.WebSPA.Server.Controllers
public class HomeController : Controller
{
private readonly IHostingEnvironment _env;
private readonly IOptions<AppSettings> _settings;
private readonly IOptionsSnapshot<AppSettings> _settings;
public HomeController(IHostingEnvironment env, IOptions<AppSettings> settings)
public HomeController(IHostingEnvironment env, IOptionsSnapshot<AppSettings> settings)
{
_env = env;
_settings = settings;


+ 19
- 18
src/Web/WebSPA/eShopOnContainers.WebSPA/project.json View File

@ -2,16 +2,16 @@
"userSecretsId": "aspnetcorespa-c23d27a4-eb88-4b18-9b77-2a93f3b15119",
"dependencies": {
"Microsoft.NETCore.App": {
"version": "1.0.0",
"version": "1.1.0",
"type": "platform"
},
"Microsoft.Extensions.Configuration.UserSecrets": "1.0.0",
"Microsoft.AspNetCore.Authentication.Cookies": "1.0.0",
"Microsoft.AspNetCore.Diagnostics": "1.0.0",
"Microsoft.AspNetCore.Mvc": "1.0.1",
"Microsoft.AspNetCore.Cors": "1.0.0",
"Microsoft.AspNetCore.Antiforgery": "1.0.1",
"Microsoft.AspNetCore.Authorization": "1.0.0",
"Microsoft.Extensions.Configuration.UserSecrets": "1.1.0",
"Microsoft.AspNetCore.Authentication.Cookies": "1.1.0",
"Microsoft.AspNetCore.Diagnostics": "1.1.0",
"Microsoft.AspNetCore.Mvc": "1.1.1",
"Microsoft.AspNetCore.Cors": "1.1.0",
"Microsoft.AspNetCore.Antiforgery": "1.1.0",
"Microsoft.AspNetCore.Authorization": "1.1.0",
"Newtonsoft.Json": "9.0.1",
"Webpack": "3.0.0",
"Microsoft.AspNetCore.AngularServices": "1.0.0-beta-000014",
@ -19,15 +19,15 @@
"version": "1.0.0-preview2-final",
"type": "build"
},
"Microsoft.AspNetCore.Server.IISIntegration": "1.0.0",
"Microsoft.AspNetCore.Server.Kestrel": "1.0.0",
"Microsoft.AspNetCore.StaticFiles": "1.0.0",
"Microsoft.Extensions.Configuration.EnvironmentVariables": "1.0.0",
"Microsoft.Extensions.Configuration.Json": "1.0.0",
"Microsoft.Extensions.Logging": "1.0.0",
"Microsoft.Extensions.Logging.Console": "1.0.0",
"Microsoft.Extensions.Logging.Debug": "1.0.0",
"Microsoft.Extensions.Options.ConfigurationExtensions": "1.0.0",
"Microsoft.AspNetCore.Server.IISIntegration": "1.1.0",
"Microsoft.AspNetCore.Server.Kestrel": "1.1.0",
"Microsoft.AspNetCore.StaticFiles": "1.1.0",
"Microsoft.Extensions.Configuration.EnvironmentVariables": "1.1.0",
"Microsoft.Extensions.Configuration.Json": "1.1.0",
"Microsoft.Extensions.Logging": "1.1.0",
"Microsoft.Extensions.Logging.Console": "1.1.0",
"Microsoft.Extensions.Logging.Debug": "1.1.0",
"Microsoft.Extensions.Options.ConfigurationExtensions": "1.1.0",
"Microsoft.VisualStudio.Web.CodeGeneration.Tools": {
"version": "1.0.0-preview2-final",
"type": "build"
@ -36,7 +36,8 @@
"version": "1.0.0-preview2-final",
"type": "build"
},
"Microsoft.AspNetCore.Http.Abstractions": "1.0.0"
"Microsoft.AspNetCore.Http.Abstractions": "1.1.0",
"Microsoft.Extensions.Options": "1.1.0"
},
"tools": {
"Microsoft.DotNet.Watcher.Tools": {


+ 3
- 3
test/Services/UnitTest/Ordering/Application/NewOrderCommandHandlerTest.cs View File

@ -25,7 +25,7 @@ namespace UnitTest.Ordering.Application
public async Task Handle_returns_true_when_order_is_persisted_succesfully()
{
// Arrange
_buyerRepositoryMock.Setup(buyerRepo => buyerRepo.FindAsync(FakeOrderRequestWithBuyer().BuyerFullName))
_buyerRepositoryMock.Setup(buyerRepo => buyerRepo.FindAsync(FakeOrderRequestWithBuyer().BuyerIdentityGuid))
.Returns(Task.FromResult<Buyer>(FakeBuyer()));
_buyerRepositoryMock.Setup(buyerRepo => buyerRepo.UnitOfWork.SaveChangesAsync(default(CancellationToken)))
@ -48,7 +48,7 @@ namespace UnitTest.Ordering.Application
[Fact]
public async Task Handle_return_false_if_order_is_not_persisted()
{
_buyerRepositoryMock.Setup(buyerRepo => buyerRepo.FindAsync(FakeOrderRequestWithBuyer().BuyerFullName))
_buyerRepositoryMock.Setup(buyerRepo => buyerRepo.FindAsync(FakeOrderRequestWithBuyer().BuyerIdentityGuid))
.Returns(Task.FromResult<Buyer>(FakeBuyer()));
_buyerRepositoryMock.Setup(buyerRepo => buyerRepo.UnitOfWork.SaveChangesAsync(default(CancellationToken)))
@ -80,7 +80,7 @@ namespace UnitTest.Ordering.Application
{
return new CreateOrderCommand
{
BuyerFullName = "1234",
BuyerIdentityGuid = "1234",
CardNumber = "1234",
CardExpiration = DateTime.Now.AddYears(1),
CardSecurityNumber = "123",


Loading…
Cancel
Save