Browse Source

Remove old code and projects. Add MediatR. Added first commands. Review Entities and domain. Create queries

pull/49/merge
Unai 8 years ago
parent
commit
95af336404
48 changed files with 503 additions and 1843 deletions
  1. +51
    -29
      eShopOnContainers.sln
  2. +8
    -2
      src/Services/Catalog/Catalog.API/Startup.cs
  3. +1
    -0
      src/Services/Catalog/Catalog.API/project.json
  4. +0
    -41
      src/Services/Ordering/Ordering.API/.vscode/launch.json
  5. +0
    -16
      src/Services/Ordering/Ordering.API/.vscode/tasks.json
  6. +0
    -23
      src/Services/Ordering/Ordering.API/Controllers/EnvironmentInfoController.cs
  7. +0
    -129
      src/Services/Ordering/Ordering.API/Controllers/OrderingController.cs
  8. +97
    -0
      src/Services/Ordering/Ordering.API/Controllers/OrdersController.cs
  9. +0
    -121
      src/Services/Ordering/Ordering.API/Migrations/20160913204939_Migration1.Designer.cs
  10. +0
    -123
      src/Services/Ordering/Ordering.API/Migrations/20160913204939_Migration1.cs
  11. +0
    -121
      src/Services/Ordering/Ordering.API/Migrations/20161005002014_Migration_Baseline.Designer.cs
  12. +0
    -19
      src/Services/Ordering/Ordering.API/Migrations/20161005002014_Migration_Baseline.cs
  13. +0
    -121
      src/Services/Ordering/Ordering.API/Migrations/20161005003321_Migration_Cero.Designer.cs
  14. +0
    -19
      src/Services/Ordering/Ordering.API/Migrations/20161005003321_Migration_Cero.cs
  15. +0
    -123
      src/Services/Ordering/Ordering.API/Migrations/20161011040943_Migration2.Designer.cs
  16. +0
    -24
      src/Services/Ordering/Ordering.API/Migrations/20161011040943_Migration2.cs
  17. +0
    -123
      src/Services/Ordering/Ordering.API/Migrations/20161011041130_Migration3.Designer.cs
  18. +0
    -19
      src/Services/Ordering/Ordering.API/Migrations/20161011041130_Migration3.cs
  19. +0
    -122
      src/Services/Ordering/Ordering.API/Migrations/OrderingDbContextModelSnapshot.cs
  20. +29
    -27
      src/Services/Ordering/Ordering.API/Startup.cs
  21. +6
    -1
      src/Services/Ordering/Ordering.API/project.json
  22. +15
    -0
      src/Services/Ordering/Ordering.Application/Commands/CancelOrderRequest.cs
  23. +15
    -0
      src/Services/Ordering/Ordering.Application/Commands/CancelOrderRequestHandler.cs
  24. +15
    -0
      src/Services/Ordering/Ordering.Application/Commands/NewOrderREquestHandler.cs
  25. +12
    -0
      src/Services/Ordering/Ordering.Application/Commands/NewOrderRequest.cs
  26. +19
    -0
      src/Services/Ordering/Ordering.Application/Ordering.Application.xproj
  27. +19
    -0
      src/Services/Ordering/Ordering.Application/Properties/AssemblyInfo.cs
  28. +11
    -0
      src/Services/Ordering/Ordering.Application/Queries/IOrderQueries.cs
  29. +13
    -0
      src/Services/Ordering/Ordering.Application/Queries/OrderQueries.cs
  30. +16
    -0
      src/Services/Ordering/Ordering.Application/project.json
  31. +29
    -0
      src/Services/Ordering/Ordering.Domain/Address.cs
  32. +0
    -49
      src/Services/Ordering/Ordering.Domain/AggregatesModel/Buyer/Buyer.cs
  33. +0
    -70
      src/Services/Ordering/Ordering.Domain/AggregatesModel/Order/Address.cs
  34. +0
    -112
      src/Services/Ordering/Ordering.Domain/AggregatesModel/Order/Order.cs
  35. +0
    -33
      src/Services/Ordering/Ordering.Domain/AggregatesModel/Order/OrderItem.cs
  36. +0
    -18
      src/Services/Ordering/Ordering.Domain/AggregatesModel/Order/OrderStatus.cs
  37. +12
    -0
      src/Services/Ordering/Ordering.Domain/Buyer.cs
  38. +0
    -15
      src/Services/Ordering/Ordering.Domain/Contracts/IBuyerRepository.cs
  39. +0
    -20
      src/Services/Ordering/Ordering.Domain/Contracts/IOrderRepository.cs
  40. +30
    -0
      src/Services/Ordering/Ordering.Domain/Order.cs
  41. +25
    -0
      src/Services/Ordering/Ordering.Domain/OrderItem.cs
  42. +59
    -0
      src/Services/Ordering/Ordering.Domain/OrderStatus.cs
  43. +8
    -66
      src/Services/Ordering/Ordering.Domain/SeedWork/Entity.cs
  44. +0
    -47
      src/Services/Ordering/Ordering.Domain/SeedWork/IdentityGenerator.cs
  45. +13
    -37
      src/Services/Ordering/Ordering.Domain/SeedWork/ValueObject.cs
  46. +0
    -24
      src/Services/Ordering/Ordering.SqlData/Queries/IOrderdingQueries.cs
  47. +0
    -98
      src/Services/Ordering/Ordering.SqlData/Queries/OrderingQueries.cs
  48. +0
    -51
      src/Services/Ordering/Ordering.SqlData/Repositories/OrderRepository.cs

+ 51
- 29
eShopOnContainers.sln View File

@ -32,8 +32,6 @@ Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Ordering.API", "src\Service
EndProject
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Ordering.Domain", "src\Services\Ordering\Ordering.Domain\Ordering.Domain.xproj", "{F5598DCB-6DDE-4661-AD9D-A55612DA7E76}"
EndProject
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Ordering.SqlData", "src\Services\Ordering\Ordering.SqlData\Ordering.SqlData.xproj", "{5DA6EF13-C7E0-4EC4-8599-A61C6AC2628D}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{A857AD10-40FF-4303-BEC2-FF1C58D5735E}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Services", "Services", "{EF0337F2-ED00-4643-89FD-EE10863F1870}"
@ -60,6 +58,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Targets", "Targets", "{9CC7
EndProject
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "eShopOnContainers.WebSPA", "src\Web\WebSPA\eShopOnContainers.WebSPA\eShopOnContainers.WebSPA.xproj", "{9842DB3A-1391-48C7-A49C-2FABD0A18AC2}"
EndProject
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Ordering.Application", "src\Services\Ordering\Ordering.Application\Ordering.Application.xproj", "{4193CAA3-A1C3-4818-A06F-A2D85FDE77E7}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Ad-Hoc|Any CPU = Ad-Hoc|Any CPU
@ -192,32 +192,6 @@ Global
{F5598DCB-6DDE-4661-AD9D-A55612DA7E76}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
{F5598DCB-6DDE-4661-AD9D-A55612DA7E76}.Release|x64.ActiveCfg = Release|Any CPU
{F5598DCB-6DDE-4661-AD9D-A55612DA7E76}.Release|x86.ActiveCfg = Release|Any CPU
{5DA6EF13-C7E0-4EC4-8599-A61C6AC2628D}.Ad-Hoc|Any CPU.ActiveCfg = Release|Any CPU
{5DA6EF13-C7E0-4EC4-8599-A61C6AC2628D}.Ad-Hoc|ARM.ActiveCfg = Release|Any CPU
{5DA6EF13-C7E0-4EC4-8599-A61C6AC2628D}.Ad-Hoc|iPhone.ActiveCfg = Release|Any CPU
{5DA6EF13-C7E0-4EC4-8599-A61C6AC2628D}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Release|Any CPU
{5DA6EF13-C7E0-4EC4-8599-A61C6AC2628D}.Ad-Hoc|x64.ActiveCfg = Release|Any CPU
{5DA6EF13-C7E0-4EC4-8599-A61C6AC2628D}.Ad-Hoc|x86.ActiveCfg = Release|Any CPU
{5DA6EF13-C7E0-4EC4-8599-A61C6AC2628D}.AppStore|Any CPU.ActiveCfg = Release|Any CPU
{5DA6EF13-C7E0-4EC4-8599-A61C6AC2628D}.AppStore|ARM.ActiveCfg = Release|Any CPU
{5DA6EF13-C7E0-4EC4-8599-A61C6AC2628D}.AppStore|iPhone.ActiveCfg = Release|Any CPU
{5DA6EF13-C7E0-4EC4-8599-A61C6AC2628D}.AppStore|iPhoneSimulator.ActiveCfg = Release|Any CPU
{5DA6EF13-C7E0-4EC4-8599-A61C6AC2628D}.AppStore|x64.ActiveCfg = Release|Any CPU
{5DA6EF13-C7E0-4EC4-8599-A61C6AC2628D}.AppStore|x86.ActiveCfg = Release|Any CPU
{5DA6EF13-C7E0-4EC4-8599-A61C6AC2628D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{5DA6EF13-C7E0-4EC4-8599-A61C6AC2628D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{5DA6EF13-C7E0-4EC4-8599-A61C6AC2628D}.Debug|ARM.ActiveCfg = Debug|Any CPU
{5DA6EF13-C7E0-4EC4-8599-A61C6AC2628D}.Debug|iPhone.ActiveCfg = Debug|Any CPU
{5DA6EF13-C7E0-4EC4-8599-A61C6AC2628D}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{5DA6EF13-C7E0-4EC4-8599-A61C6AC2628D}.Debug|x64.ActiveCfg = Debug|Any CPU
{5DA6EF13-C7E0-4EC4-8599-A61C6AC2628D}.Debug|x86.ActiveCfg = Debug|Any CPU
{5DA6EF13-C7E0-4EC4-8599-A61C6AC2628D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{5DA6EF13-C7E0-4EC4-8599-A61C6AC2628D}.Release|Any CPU.Build.0 = Release|Any CPU
{5DA6EF13-C7E0-4EC4-8599-A61C6AC2628D}.Release|ARM.ActiveCfg = Release|Any CPU
{5DA6EF13-C7E0-4EC4-8599-A61C6AC2628D}.Release|iPhone.ActiveCfg = Release|Any CPU
{5DA6EF13-C7E0-4EC4-8599-A61C6AC2628D}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
{5DA6EF13-C7E0-4EC4-8599-A61C6AC2628D}.Release|x64.ActiveCfg = Release|Any CPU
{5DA6EF13-C7E0-4EC4-8599-A61C6AC2628D}.Release|x86.ActiveCfg = Release|Any CPU
{A0AFC432-3846-4B4E-BD8E-3C8C896F4967}.Ad-Hoc|Any CPU.ActiveCfg = Release|Any CPU
{A0AFC432-3846-4B4E-BD8E-3C8C896F4967}.Ad-Hoc|ARM.ActiveCfg = Release|Any CPU
{A0AFC432-3846-4B4E-BD8E-3C8C896F4967}.Ad-Hoc|iPhone.ActiveCfg = Release|Any CPU
@ -556,6 +530,54 @@ Global
{9842DB3A-1391-48C7-A49C-2FABD0A18AC2}.Release|x64.Build.0 = Release|Any CPU
{9842DB3A-1391-48C7-A49C-2FABD0A18AC2}.Release|x86.ActiveCfg = Release|Any CPU
{9842DB3A-1391-48C7-A49C-2FABD0A18AC2}.Release|x86.Build.0 = Release|Any CPU
{4193CAA3-A1C3-4818-A06F-A2D85FDE77E7}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU
{4193CAA3-A1C3-4818-A06F-A2D85FDE77E7}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU
{4193CAA3-A1C3-4818-A06F-A2D85FDE77E7}.Ad-Hoc|ARM.ActiveCfg = Debug|Any CPU
{4193CAA3-A1C3-4818-A06F-A2D85FDE77E7}.Ad-Hoc|ARM.Build.0 = Debug|Any CPU
{4193CAA3-A1C3-4818-A06F-A2D85FDE77E7}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU
{4193CAA3-A1C3-4818-A06F-A2D85FDE77E7}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU
{4193CAA3-A1C3-4818-A06F-A2D85FDE77E7}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{4193CAA3-A1C3-4818-A06F-A2D85FDE77E7}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU
{4193CAA3-A1C3-4818-A06F-A2D85FDE77E7}.Ad-Hoc|x64.ActiveCfg = Debug|Any CPU
{4193CAA3-A1C3-4818-A06F-A2D85FDE77E7}.Ad-Hoc|x64.Build.0 = Debug|Any CPU
{4193CAA3-A1C3-4818-A06F-A2D85FDE77E7}.Ad-Hoc|x86.ActiveCfg = Debug|Any CPU
{4193CAA3-A1C3-4818-A06F-A2D85FDE77E7}.Ad-Hoc|x86.Build.0 = Debug|Any CPU
{4193CAA3-A1C3-4818-A06F-A2D85FDE77E7}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU
{4193CAA3-A1C3-4818-A06F-A2D85FDE77E7}.AppStore|Any CPU.Build.0 = Debug|Any CPU
{4193CAA3-A1C3-4818-A06F-A2D85FDE77E7}.AppStore|ARM.ActiveCfg = Debug|Any CPU
{4193CAA3-A1C3-4818-A06F-A2D85FDE77E7}.AppStore|ARM.Build.0 = Debug|Any CPU
{4193CAA3-A1C3-4818-A06F-A2D85FDE77E7}.AppStore|iPhone.ActiveCfg = Debug|Any CPU
{4193CAA3-A1C3-4818-A06F-A2D85FDE77E7}.AppStore|iPhone.Build.0 = Debug|Any CPU
{4193CAA3-A1C3-4818-A06F-A2D85FDE77E7}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{4193CAA3-A1C3-4818-A06F-A2D85FDE77E7}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU
{4193CAA3-A1C3-4818-A06F-A2D85FDE77E7}.AppStore|x64.ActiveCfg = Debug|Any CPU
{4193CAA3-A1C3-4818-A06F-A2D85FDE77E7}.AppStore|x64.Build.0 = Debug|Any CPU
{4193CAA3-A1C3-4818-A06F-A2D85FDE77E7}.AppStore|x86.ActiveCfg = Debug|Any CPU
{4193CAA3-A1C3-4818-A06F-A2D85FDE77E7}.AppStore|x86.Build.0 = Debug|Any CPU
{4193CAA3-A1C3-4818-A06F-A2D85FDE77E7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{4193CAA3-A1C3-4818-A06F-A2D85FDE77E7}.Debug|Any CPU.Build.0 = Debug|Any CPU
{4193CAA3-A1C3-4818-A06F-A2D85FDE77E7}.Debug|ARM.ActiveCfg = Debug|Any CPU
{4193CAA3-A1C3-4818-A06F-A2D85FDE77E7}.Debug|ARM.Build.0 = Debug|Any CPU
{4193CAA3-A1C3-4818-A06F-A2D85FDE77E7}.Debug|iPhone.ActiveCfg = Debug|Any CPU
{4193CAA3-A1C3-4818-A06F-A2D85FDE77E7}.Debug|iPhone.Build.0 = Debug|Any CPU
{4193CAA3-A1C3-4818-A06F-A2D85FDE77E7}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{4193CAA3-A1C3-4818-A06F-A2D85FDE77E7}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
{4193CAA3-A1C3-4818-A06F-A2D85FDE77E7}.Debug|x64.ActiveCfg = Debug|Any CPU
{4193CAA3-A1C3-4818-A06F-A2D85FDE77E7}.Debug|x64.Build.0 = Debug|Any CPU
{4193CAA3-A1C3-4818-A06F-A2D85FDE77E7}.Debug|x86.ActiveCfg = Debug|Any CPU
{4193CAA3-A1C3-4818-A06F-A2D85FDE77E7}.Debug|x86.Build.0 = Debug|Any CPU
{4193CAA3-A1C3-4818-A06F-A2D85FDE77E7}.Release|Any CPU.ActiveCfg = Release|Any CPU
{4193CAA3-A1C3-4818-A06F-A2D85FDE77E7}.Release|Any CPU.Build.0 = Release|Any CPU
{4193CAA3-A1C3-4818-A06F-A2D85FDE77E7}.Release|ARM.ActiveCfg = Release|Any CPU
{4193CAA3-A1C3-4818-A06F-A2D85FDE77E7}.Release|ARM.Build.0 = Release|Any CPU
{4193CAA3-A1C3-4818-A06F-A2D85FDE77E7}.Release|iPhone.ActiveCfg = Release|Any CPU
{4193CAA3-A1C3-4818-A06F-A2D85FDE77E7}.Release|iPhone.Build.0 = Release|Any CPU
{4193CAA3-A1C3-4818-A06F-A2D85FDE77E7}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
{4193CAA3-A1C3-4818-A06F-A2D85FDE77E7}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
{4193CAA3-A1C3-4818-A06F-A2D85FDE77E7}.Release|x64.ActiveCfg = Release|Any CPU
{4193CAA3-A1C3-4818-A06F-A2D85FDE77E7}.Release|x64.Build.0 = Release|Any CPU
{4193CAA3-A1C3-4818-A06F-A2D85FDE77E7}.Release|x86.ActiveCfg = Release|Any CPU
{4193CAA3-A1C3-4818-A06F-A2D85FDE77E7}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@ -571,7 +593,6 @@ Global
{42681D9D-750A-4DF7-BD9F-9292CFD5C253} = {326A7FB3-5295-468C-A4FE-67DCB823E1E5}
{231226CE-690B-4979-8870-9A79D80928E2} = {0BD0DB92-2D98-44D9-9AC0-C59186D59B0B}
{F5598DCB-6DDE-4661-AD9D-A55612DA7E76} = {0BD0DB92-2D98-44D9-9AC0-C59186D59B0B}
{5DA6EF13-C7E0-4EC4-8599-A61C6AC2628D} = {0BD0DB92-2D98-44D9-9AC0-C59186D59B0B}
{EF0337F2-ED00-4643-89FD-EE10863F1870} = {A857AD10-40FF-4303-BEC2-FF1C58D5735E}
{A0AFC432-3846-4B4E-BD8E-3C8C896F4967} = {EF0337F2-ED00-4643-89FD-EE10863F1870}
{48FC45C5-223F-4B59-AC77-6CBB1C561E85} = {932D8224-11F6-4D07-B109-DA28AD288A63}
@ -584,5 +605,6 @@ Global
{778289CA-31F7-4464-8C2A-612EE846F8A7} = {F61357CE-1CC2-410E-8776-B16EEBC98EB8}
{9CC7814B-72A6-465B-A61C-57B512DEE303} = {F61357CE-1CC2-410E-8776-B16EEBC98EB8}
{9842DB3A-1391-48C7-A49C-2FABD0A18AC2} = {E279BF0F-7F66-4F3A-A3AB-2CDA66C1CD04}
{4193CAA3-A1C3-4818-A06F-A2D85FDE77E7} = {0BD0DB92-2D98-44D9-9AC0-C59186D59B0B}
EndGlobalSection
EndGlobal

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

@ -18,8 +18,14 @@
var builder = new ConfigurationBuilder()
.SetBasePath(env.ContentRootPath)
.AddJsonFile($"settings.json", optional: false, reloadOnChange: true)
.AddJsonFile($"settings.{env.EnvironmentName}.json", optional: true)
.AddEnvironmentVariables();
.AddJsonFile($"settings.{env.EnvironmentName}.json", optional: true);
if (env.IsDevelopment())
{
builder.AddUserSecrets();
}
builder.AddEnvironmentVariables();
Configuration = builder.Build();
}


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

@ -10,6 +10,7 @@
"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",


+ 0
- 41
src/Services/Ordering/Ordering.API/.vscode/launch.json View File

@ -1,41 +0,0 @@
{
"version": "0.2.0",
"configurations": [
{
"name": ".NET Core Launch (web)",
"type": "coreclr",
"request": "launch",
"preLaunchTask": "build",
"program": "${workspaceRoot}\\bin\\Debug\\netcoreapp1.0\\Ordering.API.dll",
"args": [],
"cwd": "${workspaceRoot}",
"stopAtEntry": false,
"launchBrowser": {
"enabled": true,
"args": "${auto-detect-url}",
"windows": {
"command": "cmd.exe",
"args": "/C start ${auto-detect-url}"
},
"osx": {
"command": "open"
},
"linux": {
"command": "xdg-open"
}
},
"env": {
"ASPNETCORE_ENVIRONMENT": "Development"
},
"sourceFileMap": {
"/Views": "${workspaceRoot}/Views"
}
},
{
"name": ".NET Core Attach",
"type": "coreclr",
"request": "attach",
"processId": "${command.pickProcess}"
}
]
}

+ 0
- 16
src/Services/Ordering/Ordering.API/.vscode/tasks.json View File

@ -1,16 +0,0 @@
{
"version": "0.1.0",
"command": "dotnet",
"isShellCommand": true,
"args": [],
"tasks": [
{
"taskName": "build",
"args": [
"${workspaceRoot}\\project.json"
],
"isBuildCommand": true,
"problemMatcher": "$msCompile"
}
]
}

+ 0
- 23
src/Services/Ordering/Ordering.API/Controllers/EnvironmentInfoController.cs View File

@ -1,23 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
namespace Microsoft.eShopOnContainers.Services.Ordering.API.Controllers
{
[Route("api/[controller]")]
public class EnvironmentInfoController : Controller
{
// GET api/environmentInfo/machinename
[HttpGet("machinename")]
public dynamic GetMachineName()
{
return new
{
InstanceName = Environment.MachineName
};
}
}
}

+ 0
- 129
src/Services/Ordering/Ordering.API/Controllers/OrderingController.cs View File

@ -1,129 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.eShopOnContainers.Services.Ordering.SqlData.UnitOfWork;
using Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel;
using Microsoft.EntityFrameworkCore;
using Microsoft.eShopOnContainers.Services.Ordering.Domain.Contracts;
using Microsoft.eShopOnContainers.Services.Ordering.SqlData.Queries;
namespace Microsoft.eShopOnContainers.Services.Ordering.API.Controllers
{
[Route("api/[controller]")]
public class OrderingController : Controller
{
private IOrderRepository _orderRepository;
private IOrderdingQueries _queries;
//private OrderingDbContext _context;
public OrderingController(IOrderRepository orderRepository,
IOrderdingQueries orderingQueries //,
//OrderingDbContext context
)
{
//Injected objects from the IoC container
_orderRepository = orderRepository;
_queries = orderingQueries;
//_context = context;
}
// GET api/ordering/orders
[HttpGet("orders")]
public async Task<IActionResult> GetAllOrders()
{
dynamic response = await _queries.GetAllOrdersIncludingValueObjectsAndChildEntities();
return Ok(response);
}
// GET api/ordering/orders/xxxGUIDxxxx
[HttpGet("orders/{orderId:Guid}")]
public async Task<IActionResult> GetOrderById(Guid orderId)
{
dynamic response = await _queries.GetOrderById(orderId);
return Ok(response);
}
//(CDLTLL) - Using parameters
//Alternate method if using several parameters instead of part of the URL
// GET api/ordering/orders/?orderId=xxxGUIDxxx&otherParam=value
//[HttpGet("orders")]
//public Order GetOrderByGuid([FromUri] Guid orderId, [FromUri] string otherParam)
// POST api/ordering/orders/create
[HttpPut("orders/create")]
public async Task<IActionResult> Post([FromBody]Order order)
{
_orderRepository.Add(order);
int numChanges = await _orderRepository.UnitOfWork.CommitAsync();
return Ok(numChanges);
}
// PUT api/ordering/orders/xxxOrderGUIDxxxx/update
[HttpPut("orders/{orderId:Guid}/update")]
public async Task<IActionResult> UpdateOrder(Guid orderID, [FromBody] Order orderToUpdate)
{
_orderRepository.Update(orderToUpdate);
int numChanges = await _orderRepository.UnitOfWork.CommitAsync();
return Ok(numChanges);
}
// DELETE api/ordering/orders/xxxOrderGUIDxxxx
[HttpDelete("orders/{orderId:Guid}/remove")]
public async Task<IActionResult> Remove(Guid id)
{
await _orderRepository.Remove(id);
int numChanges = await _orderRepository.UnitOfWork.CommitAsync();
return Ok(numChanges);
}
// GET api/ordering/orders/add_test_data_and_get_all
[HttpGet("orders/add_test_data_and_get_all")]
public async Task<IActionResult> AddTestDataAndGetAllOrders()
{
//TEST ADDING ORDERS *********************************
//Create generic Address ValueObject
Address sampleAddress = new Address("15703 NE 61st Ct.",
"Redmond",
"Washington",
"WA",
"United States",
"US",
"98052",
47.661492,
-122.131309
);
//Create sample Orders
Order order1 = new Order(Guid.NewGuid(), sampleAddress, sampleAddress);
//Add a few OrderItems
order1.AddNewOrderItem(Guid.NewGuid(), 2, 25, 30);
order1.AddNewOrderItem(Guid.NewGuid(), 1, 58, 0);
order1.AddNewOrderItem(Guid.NewGuid(), 1, 60, 0);
order1.AddNewOrderItem(Guid.NewGuid(), 3, 12, 0);
order1.AddNewOrderItem(Guid.NewGuid(), 5, 3, 0);
_orderRepository.Add(order1);
int numRecs = await _orderRepository.UnitOfWork.CommitAsync();
//_context.Orders.Add(order1);
//_context.SaveChanges();
//*****************************************************
dynamic response = await _queries.GetAllOrdersIncludingValueObjectsAndChildEntities();
return Ok(response);
}
}
}

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

@ -0,0 +1,97 @@
namespace Microsoft.eShopOnContainers.Services.Ordering.API.Controllers
{
using Application.Commands;
using Application.Queries;
using MediatR;
using Microsoft.AspNetCore.Mvc;
using System;
using System.Threading.Tasks;
[Route("api/v1/[controller]")]
public class OrdersController : Controller
{
private readonly IMediator _mediator;
private readonly IOrderQueries _orderQueries;
public OrdersController(IMediator mediator,IOrderQueries orderQueries)
{
if (mediator == null)
{
throw new ArgumentNullException(nameof(mediator));
}
if (orderQueries == null)
{
throw new ArgumentNullException(nameof(orderQueries));
}
_mediator = mediator;
_orderQueries = orderQueries;
}
[Route("new")]
[HttpPost]
public async Task<IActionResult> AddOrder()
{
var newOrderRequest = new NewOrderRequest();
var added = await _mediator.SendAsync(newOrderRequest);
if (added)
{
return Ok();
}
return BadRequest();
}
[Route("cancel/{orderId:int}")]
[HttpPost]
public async Task<IActionResult> CancelOrder(int orderId)
{
var cancelOrderRequest = new CancelOrderRequest(orderId);
var cancelled = await _mediator.SendAsync(cancelOrderRequest);
if (cancelled)
{
return Ok();
}
return BadRequest();
}
[Route("{orderId:int}")]
[HttpGet]
public async Task<IActionResult> GetOrder(int orderId)
{
var order = await _orderQueries.GetOrder(orderId);
if ( order != null)
{
Ok(order);
}
return NotFound();
}
[Route("pending")]
[HttpGet]
public async Task<IActionResult> GetPendingOrders(int orderId)
{
var orders = await _orderQueries.GetPendingOrders();
if (orders.Any())
{
Ok(orders);
}
return NoContent();
}
}
}

+ 0
- 121
src/Services/Ordering/Ordering.API/Migrations/20160913204939_Migration1.Designer.cs View File

@ -1,121 +0,0 @@
using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.eShopOnContainers.Services.Ordering.SqlData.UnitOfWork;
namespace Ordering.API.Migrations
{
[DbContext(typeof(OrderingDbContext))]
[Migration("20160913204939_Migration1")]
partial class Migration1
{
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
modelBuilder
.HasAnnotation("ProductVersion", "1.0.0-rtm-21431")
.HasAnnotation("Relational:Sequence:shared.OrderSequences", "'OrderSequences', 'shared', '1001', '1', '', '', 'Int32', 'False'")
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.Address", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd();
b.Property<string>("City");
b.Property<string>("Country");
b.Property<string>("CountryCode");
b.Property<double>("Latitude");
b.Property<double>("Longitude");
b.Property<string>("State");
b.Property<string>("StateCode");
b.Property<string>("Street");
b.Property<string>("ZipCode");
b.HasKey("Id");
b.ToTable("Address");
});
modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.Order", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd();
b.Property<Guid?>("BillingAddressId");
b.Property<Guid>("BuyerId");
b.Property<DateTime>("OrderDate");
b.Property<int>("SequenceNumber")
.ValueGeneratedOnAdd()
.HasDefaultValueSql("NEXT VALUE FOR shared.OrderSequences");
b.Property<Guid?>("ShippingAddressId");
b.Property<int>("Status");
b.HasKey("Id");
b.HasIndex("BillingAddressId");
b.HasIndex("ShippingAddressId");
b.ToTable("Orders");
});
modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderItem", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd();
b.Property<decimal>("Discount");
b.Property<int>("FulfillmentRemaining");
b.Property<Guid>("OrderId");
b.Property<Guid>("ProductId");
b.Property<int>("Quantity");
b.Property<decimal>("UnitPrice");
b.HasKey("Id");
b.HasIndex("OrderId");
b.ToTable("OrderItem");
});
modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.Order", b =>
{
b.HasOne("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.Address", "BillingAddress")
.WithMany()
.HasForeignKey("BillingAddressId");
b.HasOne("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.Address", "ShippingAddress")
.WithMany()
.HasForeignKey("ShippingAddressId");
});
modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderItem", b =>
{
b.HasOne("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.Order")
.WithMany("OrderItems")
.HasForeignKey("OrderId")
.OnDelete(DeleteBehavior.Cascade);
});
}
}
}

+ 0
- 123
src/Services/Ordering/Ordering.API/Migrations/20160913204939_Migration1.cs View File

@ -1,123 +0,0 @@
using System;
using System.Collections.Generic;
using Microsoft.EntityFrameworkCore.Migrations;
namespace Ordering.API.Migrations
{
public partial class Migration1 : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.EnsureSchema(
name: "shared");
migrationBuilder.CreateSequence<int>(
name: "OrderSequences",
schema: "shared",
startValue: 1001L);
migrationBuilder.CreateTable(
name: "Address",
columns: table => new
{
Id = table.Column<Guid>(nullable: false),
City = table.Column<string>(nullable: true),
Country = table.Column<string>(nullable: true),
CountryCode = table.Column<string>(nullable: true),
Latitude = table.Column<double>(nullable: false),
Longitude = table.Column<double>(nullable: false),
State = table.Column<string>(nullable: true),
StateCode = 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: "Orders",
columns: table => new
{
Id = table.Column<Guid>(nullable: false),
BillingAddressId = table.Column<Guid>(nullable: true),
BuyerId = table.Column<Guid>(nullable: false),
OrderDate = table.Column<DateTime>(nullable: false),
SequenceNumber = table.Column<int>(nullable: false, defaultValueSql: "NEXT VALUE FOR shared.OrderSequences"),
ShippingAddressId = table.Column<Guid>(nullable: true),
Status = table.Column<int>(nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_Orders", x => x.Id);
table.ForeignKey(
name: "FK_Orders_Address_BillingAddressId",
column: x => x.BillingAddressId,
principalTable: "Address",
principalColumn: "Id",
onDelete: ReferentialAction.Restrict);
table.ForeignKey(
name: "FK_Orders_Address_ShippingAddressId",
column: x => x.ShippingAddressId,
principalTable: "Address",
principalColumn: "Id",
onDelete: ReferentialAction.Restrict);
});
migrationBuilder.CreateTable(
name: "OrderItem",
columns: table => new
{
Id = table.Column<Guid>(nullable: false),
Discount = table.Column<decimal>(nullable: false),
FulfillmentRemaining = table.Column<int>(nullable: false),
OrderId = table.Column<Guid>(nullable: false),
ProductId = table.Column<Guid>(nullable: false),
Quantity = table.Column<int>(nullable: false),
UnitPrice = table.Column<decimal>(nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_OrderItem", x => x.Id);
table.ForeignKey(
name: "FK_OrderItem_Orders_OrderId",
column: x => x.OrderId,
principalTable: "Orders",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateIndex(
name: "IX_Orders_BillingAddressId",
table: "Orders",
column: "BillingAddressId");
migrationBuilder.CreateIndex(
name: "IX_Orders_ShippingAddressId",
table: "Orders",
column: "ShippingAddressId");
migrationBuilder.CreateIndex(
name: "IX_OrderItem_OrderId",
table: "OrderItem",
column: "OrderId");
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropSequence(
name: "OrderSequences",
schema: "shared");
migrationBuilder.DropTable(
name: "OrderItem");
migrationBuilder.DropTable(
name: "Orders");
migrationBuilder.DropTable(
name: "Address");
}
}
}

+ 0
- 121
src/Services/Ordering/Ordering.API/Migrations/20161005002014_Migration_Baseline.Designer.cs View File

@ -1,121 +0,0 @@
using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.eShopOnContainers.Services.Ordering.SqlData.UnitOfWork;
namespace Ordering.API.Migrations
{
[DbContext(typeof(OrderingDbContext))]
[Migration("20161005002014_Migration_Baseline")]
partial class Migration_Baseline
{
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
modelBuilder
.HasAnnotation("ProductVersion", "1.0.0-rtm-21431")
.HasAnnotation("Relational:Sequence:shared.OrderSequences", "'OrderSequences', 'shared', '1001', '1', '', '', 'Int32', 'False'")
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.Address", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd();
b.Property<string>("City");
b.Property<string>("Country");
b.Property<string>("CountryCode");
b.Property<double>("Latitude");
b.Property<double>("Longitude");
b.Property<string>("State");
b.Property<string>("StateCode");
b.Property<string>("Street");
b.Property<string>("ZipCode");
b.HasKey("Id");
b.ToTable("Address");
});
modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.Order", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd();
b.Property<Guid?>("BillingAddressId");
b.Property<Guid>("BuyerId");
b.Property<DateTime>("OrderDate");
b.Property<int>("SequenceNumber")
.ValueGeneratedOnAdd()
.HasDefaultValueSql("NEXT VALUE FOR shared.OrderSequences");
b.Property<Guid?>("ShippingAddressId");
b.Property<int>("Status");
b.HasKey("Id");
b.HasIndex("BillingAddressId");
b.HasIndex("ShippingAddressId");
b.ToTable("Orders");
});
modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderItem", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd();
b.Property<decimal>("Discount");
b.Property<int>("FulfillmentRemaining");
b.Property<Guid>("OrderId");
b.Property<Guid>("ProductId");
b.Property<int>("Quantity");
b.Property<decimal>("UnitPrice");
b.HasKey("Id");
b.HasIndex("OrderId");
b.ToTable("OrderItem");
});
modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.Order", b =>
{
b.HasOne("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.Address", "BillingAddress")
.WithMany()
.HasForeignKey("BillingAddressId");
b.HasOne("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.Address", "ShippingAddress")
.WithMany()
.HasForeignKey("ShippingAddressId");
});
modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderItem", b =>
{
b.HasOne("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.Order")
.WithMany("OrderItems")
.HasForeignKey("OrderId")
.OnDelete(DeleteBehavior.Cascade);
});
}
}
}

+ 0
- 19
src/Services/Ordering/Ordering.API/Migrations/20161005002014_Migration_Baseline.cs View File

@ -1,19 +0,0 @@
using System;
using System.Collections.Generic;
using Microsoft.EntityFrameworkCore.Migrations;
namespace Ordering.API.Migrations
{
public partial class Migration_Baseline : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
}
protected override void Down(MigrationBuilder migrationBuilder)
{
}
}
}

+ 0
- 121
src/Services/Ordering/Ordering.API/Migrations/20161005003321_Migration_Cero.Designer.cs View File

@ -1,121 +0,0 @@
using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.eShopOnContainers.Services.Ordering.SqlData.UnitOfWork;
namespace Ordering.API.Migrations
{
[DbContext(typeof(OrderingDbContext))]
[Migration("20161005003321_Migration_Cero")]
partial class Migration_Cero
{
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
modelBuilder
.HasAnnotation("ProductVersion", "1.0.0-rtm-21431")
.HasAnnotation("Relational:Sequence:shared.OrderSequences", "'OrderSequences', 'shared', '1001', '1', '', '', 'Int32', 'False'")
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.Address", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd();
b.Property<string>("City");
b.Property<string>("Country");
b.Property<string>("CountryCode");
b.Property<double>("Latitude");
b.Property<double>("Longitude");
b.Property<string>("State");
b.Property<string>("StateCode");
b.Property<string>("Street");
b.Property<string>("ZipCode");
b.HasKey("Id");
b.ToTable("Address");
});
modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.Order", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd();
b.Property<Guid?>("BillingAddressId");
b.Property<Guid>("BuyerId");
b.Property<DateTime>("OrderDate");
b.Property<int>("SequenceNumber")
.ValueGeneratedOnAdd()
.HasDefaultValueSql("NEXT VALUE FOR shared.OrderSequences");
b.Property<Guid?>("ShippingAddressId");
b.Property<int>("Status");
b.HasKey("Id");
b.HasIndex("BillingAddressId");
b.HasIndex("ShippingAddressId");
b.ToTable("Orders");
});
modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderItem", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd();
b.Property<decimal>("Discount");
b.Property<int>("FulfillmentRemaining");
b.Property<Guid>("OrderId");
b.Property<Guid>("ProductId");
b.Property<int>("Quantity");
b.Property<decimal>("UnitPrice");
b.HasKey("Id");
b.HasIndex("OrderId");
b.ToTable("OrderItem");
});
modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.Order", b =>
{
b.HasOne("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.Address", "BillingAddress")
.WithMany()
.HasForeignKey("BillingAddressId");
b.HasOne("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.Address", "ShippingAddress")
.WithMany()
.HasForeignKey("ShippingAddressId");
});
modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderItem", b =>
{
b.HasOne("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.Order")
.WithMany("OrderItems")
.HasForeignKey("OrderId")
.OnDelete(DeleteBehavior.Cascade);
});
}
}
}

+ 0
- 19
src/Services/Ordering/Ordering.API/Migrations/20161005003321_Migration_Cero.cs View File

@ -1,19 +0,0 @@
using System;
using System.Collections.Generic;
using Microsoft.EntityFrameworkCore.Migrations;
namespace Ordering.API.Migrations
{
public partial class Migration_Cero : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
}
protected override void Down(MigrationBuilder migrationBuilder)
{
}
}
}

+ 0
- 123
src/Services/Ordering/Ordering.API/Migrations/20161011040943_Migration2.Designer.cs View File

@ -1,123 +0,0 @@
using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.eShopOnContainers.Services.Ordering.SqlData.UnitOfWork;
namespace Ordering.API.Migrations
{
[DbContext(typeof(OrderingDbContext))]
[Migration("20161011040943_Migration2")]
partial class Migration2
{
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
modelBuilder
.HasAnnotation("ProductVersion", "1.0.0-rtm-21431")
.HasAnnotation("Relational:Sequence:shared.OrderSequences", "'OrderSequences', 'shared', '1001', '1', '', '', 'Int32', 'False'")
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.Address", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd();
b.Property<string>("City");
b.Property<string>("Country");
b.Property<string>("CountryCode");
b.Property<double>("Latitude");
b.Property<double>("Longitude");
b.Property<string>("State");
b.Property<string>("StateCode");
b.Property<string>("Street");
b.Property<string>("ZipCode");
b.HasKey("Id");
b.ToTable("Address");
});
modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.Order", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd();
b.Property<Guid?>("BillingAddressId");
b.Property<Guid>("BuyerId");
b.Property<DateTime>("OrderDate");
b.Property<int>("SequenceNumber")
.ValueGeneratedOnAdd()
.HasDefaultValueSql("NEXT VALUE FOR shared.OrderSequences");
b.Property<Guid?>("ShippingAddressId");
b.Property<int>("Status");
b.HasKey("Id");
b.HasIndex("BillingAddressId");
b.HasIndex("ShippingAddressId");
b.ToTable("Orders");
});
modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderItem", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd();
b.Property<decimal>("Discount");
b.Property<int>("FulfillmentRemaining");
b.Property<Guid>("OrderId");
b.Property<Guid>("ProductId");
b.Property<string>("ProductName");
b.Property<int>("Quantity");
b.Property<decimal>("UnitPrice");
b.HasKey("Id");
b.HasIndex("OrderId");
b.ToTable("OrderItem");
});
modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.Order", b =>
{
b.HasOne("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.Address", "BillingAddress")
.WithMany()
.HasForeignKey("BillingAddressId");
b.HasOne("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.Address", "ShippingAddress")
.WithMany()
.HasForeignKey("ShippingAddressId");
});
modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderItem", b =>
{
b.HasOne("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.Order")
.WithMany("OrderItems")
.HasForeignKey("OrderId")
.OnDelete(DeleteBehavior.Cascade);
});
}
}
}

+ 0
- 24
src/Services/Ordering/Ordering.API/Migrations/20161011040943_Migration2.cs View File

@ -1,24 +0,0 @@
using System;
using System.Collections.Generic;
using Microsoft.EntityFrameworkCore.Migrations;
namespace Ordering.API.Migrations
{
public partial class Migration2 : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<string>(
name: "ProductName",
table: "OrderItem",
nullable: true);
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropColumn(
name: "ProductName",
table: "OrderItem");
}
}
}

+ 0
- 123
src/Services/Ordering/Ordering.API/Migrations/20161011041130_Migration3.Designer.cs View File

@ -1,123 +0,0 @@
using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.eShopOnContainers.Services.Ordering.SqlData.UnitOfWork;
namespace Ordering.API.Migrations
{
[DbContext(typeof(OrderingDbContext))]
[Migration("20161011041130_Migration3")]
partial class Migration3
{
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
modelBuilder
.HasAnnotation("ProductVersion", "1.0.0-rtm-21431")
.HasAnnotation("Relational:Sequence:shared.OrderSequences", "'OrderSequences', 'shared', '1001', '1', '', '', 'Int32', 'False'")
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.Address", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd();
b.Property<string>("City");
b.Property<string>("Country");
b.Property<string>("CountryCode");
b.Property<double>("Latitude");
b.Property<double>("Longitude");
b.Property<string>("State");
b.Property<string>("StateCode");
b.Property<string>("Street");
b.Property<string>("ZipCode");
b.HasKey("Id");
b.ToTable("Address");
});
modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.Order", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd();
b.Property<Guid?>("BillingAddressId");
b.Property<Guid>("BuyerId");
b.Property<DateTime>("OrderDate");
b.Property<int>("SequenceNumber")
.ValueGeneratedOnAdd()
.HasDefaultValueSql("NEXT VALUE FOR shared.OrderSequences");
b.Property<Guid?>("ShippingAddressId");
b.Property<int>("Status");
b.HasKey("Id");
b.HasIndex("BillingAddressId");
b.HasIndex("ShippingAddressId");
b.ToTable("Orders");
});
modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderItem", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd();
b.Property<decimal>("Discount");
b.Property<int>("FulfillmentRemaining");
b.Property<Guid>("OrderId");
b.Property<Guid>("ProductId");
b.Property<string>("ProductName");
b.Property<int>("Quantity");
b.Property<decimal>("UnitPrice");
b.HasKey("Id");
b.HasIndex("OrderId");
b.ToTable("OrderItem");
});
modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.Order", b =>
{
b.HasOne("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.Address", "BillingAddress")
.WithMany()
.HasForeignKey("BillingAddressId");
b.HasOne("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.Address", "ShippingAddress")
.WithMany()
.HasForeignKey("ShippingAddressId");
});
modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderItem", b =>
{
b.HasOne("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.Order")
.WithMany("OrderItems")
.HasForeignKey("OrderId")
.OnDelete(DeleteBehavior.Cascade);
});
}
}
}

+ 0
- 19
src/Services/Ordering/Ordering.API/Migrations/20161011041130_Migration3.cs View File

@ -1,19 +0,0 @@
using System;
using System.Collections.Generic;
using Microsoft.EntityFrameworkCore.Migrations;
namespace Ordering.API.Migrations
{
public partial class Migration3 : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
}
protected override void Down(MigrationBuilder migrationBuilder)
{
}
}
}

+ 0
- 122
src/Services/Ordering/Ordering.API/Migrations/OrderingDbContextModelSnapshot.cs View File

@ -1,122 +0,0 @@
using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.eShopOnContainers.Services.Ordering.SqlData.UnitOfWork;
namespace Ordering.API.Migrations
{
[DbContext(typeof(OrderingDbContext))]
partial class OrderingDbContextModelSnapshot : ModelSnapshot
{
protected override void BuildModel(ModelBuilder modelBuilder)
{
modelBuilder
.HasAnnotation("ProductVersion", "1.0.0-rtm-21431")
.HasAnnotation("Relational:Sequence:shared.OrderSequences", "'OrderSequences', 'shared', '1001', '1', '', '', 'Int32', 'False'")
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.Address", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd();
b.Property<string>("City");
b.Property<string>("Country");
b.Property<string>("CountryCode");
b.Property<double>("Latitude");
b.Property<double>("Longitude");
b.Property<string>("State");
b.Property<string>("StateCode");
b.Property<string>("Street");
b.Property<string>("ZipCode");
b.HasKey("Id");
b.ToTable("Address");
});
modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.Order", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd();
b.Property<Guid?>("BillingAddressId");
b.Property<Guid>("BuyerId");
b.Property<DateTime>("OrderDate");
b.Property<int>("SequenceNumber")
.ValueGeneratedOnAdd()
.HasDefaultValueSql("NEXT VALUE FOR shared.OrderSequences");
b.Property<Guid?>("ShippingAddressId");
b.Property<int>("Status");
b.HasKey("Id");
b.HasIndex("BillingAddressId");
b.HasIndex("ShippingAddressId");
b.ToTable("Orders");
});
modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderItem", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd();
b.Property<decimal>("Discount");
b.Property<int>("FulfillmentRemaining");
b.Property<Guid>("OrderId");
b.Property<Guid>("ProductId");
b.Property<string>("ProductName");
b.Property<int>("Quantity");
b.Property<decimal>("UnitPrice");
b.HasKey("Id");
b.HasIndex("OrderId");
b.ToTable("OrderItem");
});
modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.Order", b =>
{
b.HasOne("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.Address", "BillingAddress")
.WithMany()
.HasForeignKey("BillingAddressId");
b.HasOne("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.Address", "ShippingAddress")
.WithMany()
.HasForeignKey("ShippingAddressId");
});
modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderItem", b =>
{
b.HasOne("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.Order")
.WithMany("OrderItems")
.HasForeignKey("OrderId")
.OnDelete(DeleteBehavior.Cascade);
});
}
}
}

+ 29
- 27
src/Services/Ordering/Ordering.API/Startup.cs View File

@ -1,21 +1,13 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.eShopOnContainers.Services.Ordering.SqlData.UnitOfWork;
using Microsoft.EntityFrameworkCore;
using Microsoft.eShopOnContainers.Services.Ordering.Domain.Contracts;
using Microsoft.eShopOnContainers.Services.Ordering.SqlData.Repositories;
using Microsoft.eShopOnContainers.Services.Ordering.SqlData.Queries;
namespace Microsoft.eShopOnContainers.Services.Ordering.API
namespace Microsoft.eShopOnContainers.Services.Ordering.API
{
using MediatR;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
public class Startup
{
public Startup(IHostingEnvironment env)
@ -37,27 +29,34 @@ namespace Microsoft.eShopOnContainers.Services.Ordering.API
public IConfigurationRoot Configuration { get; }
// This method gets called by the runtime.
// Use this method to add services to the IoC container.
public void ConfigureServices(IServiceCollection services)
{
// Add framework services.
services.AddMvc();
//services.AddEntityFrameworkSqlServer()
// .AddDbContext<OrderingDbContext>(options =>
// {
// options.UseSqlServer(Configuration["ConnectionString"]);
// });
var connString = Configuration["ConnectionString"];
services.AddDbContext<OrderingDbContext>(options =>
services.AddSwaggerGen();
services.ConfigureSwaggerGen(options =>
{
options.UseSqlServer(connString)
.UseSqlServer(connString, b => b.MigrationsAssembly("Ordering.API"));
options.DescribeAllEnumsAsStrings();
options.SingleApiVersion(new Swashbuckle.Swagger.Model.Info()
{
Title = "Ordering HTTP API",
Version = "v1",
Description = "The Ordering Service HTTP API",
TermsOfService = "Terms Of Service"
});
});
services.AddTransient<IOrderRepository, OrderRepository>();
services.AddTransient<IOrderdingQueries, OrderingQueries>();
services.AddMediatR(typeof(Startup)); //TODO:pending
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
loggerFactory.AddConsole(Configuration.GetSection("Logging"));
@ -69,6 +68,9 @@ namespace Microsoft.eShopOnContainers.Services.Ordering.API
}
app.UseMvc();
app.UseSwagger()
.UseSwaggerUi();
}
}
}

+ 6
- 1
src/Services/Ordering/Ordering.API/project.json View File

@ -4,6 +4,8 @@
"version": "1.0.0",
"type": "platform"
},
"MediatR.Extensions.Microsoft.DependencyInjection": "1.0.1",
"Microsoft.Extensions.DependencyInjection": "1.0.0",
"Microsoft.AspNetCore.Mvc": "1.0.0",
"Microsoft.AspNetCore.Server.IISIntegration": "1.0.0",
"Microsoft.AspNetCore.Server.Kestrel": "1.0.0",
@ -20,8 +22,11 @@
"Microsoft.EntityFrameworkCore.SqlServer.Design": "1.0.0",
"Microsoft.EntityFrameworkCore.Tools": "1.0.0-preview2-final",
"Microsoft.AspNetCore.Diagnostics": "1.0.0",
"Ordering.Application": "1.0.0-*",
"Ordering.Domain": "1.0.0-*",
"Ordering.SqlData": "1.0.0-*"
"Ordering.SqlData": "1.0.0-*",
"Swashbuckle": "6.0.0-beta902",
"MediatR": "2.1.0"
},
"tools": {
"Microsoft.EntityFrameworkCore.Tools": "1.0.0-preview2-final",


+ 15
- 0
src/Services/Ordering/Ordering.Application/Commands/CancelOrderRequest.cs View File

@ -0,0 +1,15 @@
namespace Microsoft.eShopOnContainers.Services.Ordering.Application.Commands
{
using MediatR;
public class CancelOrderRequest
: IAsyncRequest<bool>
{
public int OrderId { get; private set; }
public CancelOrderRequest(int orderId)
{
OrderId = orderId;
}
}
}

+ 15
- 0
src/Services/Ordering/Ordering.Application/Commands/CancelOrderRequestHandler.cs View File

@ -0,0 +1,15 @@
namespace Microsoft.eShopOnContainers.Services.Ordering.Application.Commands
{
using MediatR;
using System;
using System.Threading.Tasks;
public class CancelOrderRequestHandler
: IAsyncRequestHandler<CancelOrderRequest, bool>
{
public Task<bool> Handle(CancelOrderRequest message)
{
throw new NotImplementedException();
}
}
}

+ 15
- 0
src/Services/Ordering/Ordering.Application/Commands/NewOrderREquestHandler.cs View File

@ -0,0 +1,15 @@
namespace Microsoft.eShopOnContainers.Services.Ordering.Application.Commands
{
using MediatR;
using System;
using System.Threading.Tasks;
public class NewOrderREquestHandler
: IAsyncRequestHandler<NewOrderRequest, bool>
{
public Task<bool> Handle(NewOrderRequest message)
{
throw new NotImplementedException();
}
}
}

+ 12
- 0
src/Services/Ordering/Ordering.Application/Commands/NewOrderRequest.cs View File

@ -0,0 +1,12 @@
namespace Microsoft.eShopOnContainers.Services.Ordering.Application.Commands
{
using MediatR;
public class NewOrderRequest
:IAsyncRequest<bool>
{
public NewOrderRequest()
{
}
}
}

+ 19
- 0
src/Services/Ordering/Ordering.Application/Ordering.Application.xproj View File

@ -0,0 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">14.0</VisualStudioVersion>
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
</PropertyGroup>
<Import Project="$(VSToolsPath)\DotNet\Microsoft.DotNet.Props" Condition="'$(VSToolsPath)' != ''" />
<PropertyGroup Label="Globals">
<ProjectGuid>4193caa3-a1c3-4818-a06f-a2d85fde77e7</ProjectGuid>
<RootNamespace>Microsoft.eShopOnContainers.Services.Ordering.Application</RootNamespace>
<BaseIntermediateOutputPath Condition="'$(BaseIntermediateOutputPath)'=='' ">.\obj</BaseIntermediateOutputPath>
<OutputPath Condition="'$(OutputPath)'=='' ">.\bin\</OutputPath>
<TargetFrameworkVersion>v4.5.1</TargetFrameworkVersion>
</PropertyGroup>
<PropertyGroup>
<SchemaVersion>2.0</SchemaVersion>
</PropertyGroup>
<Import Project="$(VSToolsPath)\DotNet\Microsoft.DotNet.targets" Condition="'$(VSToolsPath)' != ''" />
</Project>

+ 19
- 0
src/Services/Ordering/Ordering.Application/Properties/AssemblyInfo.cs View File

@ -0,0 +1,19 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("Ordering.Application")]
[assembly: AssemblyTrademark("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("4193caa3-a1c3-4818-a06f-a2d85fde77e7")]

+ 11
- 0
src/Services/Ordering/Ordering.Application/Queries/IOrderQueries.cs View File

@ -0,0 +1,11 @@
namespace Microsoft.eShopOnContainers.Services.Ordering.Application.Queries
{
using System.Threading.Tasks;
public interface IOrderQueries
{
Task<dynamic> GetOrder(int id);
Task<dynamic> GetPendingOrders();
}
}

+ 13
- 0
src/Services/Ordering/Ordering.Application/Queries/OrderQueries.cs View File

@ -0,0 +1,13 @@

namespace Microsoft.eShopOnContainers.Services.Ordering.Application.Queries
{
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
public class OrderQueries
{
}
}

+ 16
- 0
src/Services/Ordering/Ordering.Application/project.json View File

@ -0,0 +1,16 @@
{
"version": "1.0.0-*",
"dependencies": {
"NETStandard.Library": "1.6.0",
"MediatR": "2.1.0",
"System.Dynamic.Runtime": "4.0.11",
"Microsoft.CSharp": "4.0.1"
},
"frameworks": {
"netstandard1.6": {
"imports": "dnxcore50"
}
}
}

+ 29
- 0
src/Services/Ordering/Ordering.Domain/Address.cs View File

@ -0,0 +1,29 @@
namespace Microsoft.eShopOnContainers.Services.Ordering.Domain
{
using Microsoft.eShopOnContainers.Services.Ordering.Domain.SeedWork;
using System;
public class Address
: Entity
{
public String Street { get; private set; }
public String City { get; private set; }
public String State { get; private set; }
public String StateCode { get; private set; }
public String Country { get; private set; }
public String CountryCode { get; private set; }
public String ZipCode { get; private set; }
public double Latitude { get; private set; }
public double Longitude { get; private set; }
protected Address() { }
}
}

+ 0
- 49
src/Services/Ordering/Ordering.Domain/AggregatesModel/Buyer/Buyer.cs View File

@ -1,49 +0,0 @@
using System;
using Microsoft.eShopOnContainers.Services.Ordering.Domain.SeedWork;
namespace Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel
{
public class Buyer : Entity, IAggregateRoot
{
public Buyer(Guid buyerId, string name, string lastName, string email, Address address, string phoneNumber)
{
this.Id = buyerId;
this.Name = name;
this.LastName = lastName;
this.Email = email;
this.Address = address;
this.PhoneNumber = phoneNumber;
}
public virtual string Name
{
get;
private set;
}
public virtual string LastName
{
get;
private set;
}
public virtual string Email
{
get;
private set;
}
public virtual Address Address
{
get;
private set;
}
public virtual string PhoneNumber
{
get;
private set;
}
}
}

+ 0
- 70
src/Services/Ordering/Ordering.Domain/AggregatesModel/Order/Address.cs View File

@ -1,70 +0,0 @@
using System;
using System.Collections.Generic;
using Microsoft.eShopOnContainers.Services.Ordering.Domain.SeedWork;
namespace Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel
{
public class Address : ValueObject<Address>
{
public Address(string street,
string city,
string state,
string stateCode,
string country,
string countryCode,
string zipCode,
double latitude = 0,
double longitude = 0
)
{
if (street == null)
throw new ArgumentNullException("street");
if (city == null)
throw new ArgumentNullException("city");
if (state == null)
throw new ArgumentNullException("state");
if (stateCode == null)
throw new ArgumentNullException("stateCode");
if (country == null)
throw new ArgumentNullException("country");
if (countryCode == null)
throw new ArgumentNullException("countryCode");
if (zipCode == null)
throw new ArgumentNullException("zipCode");
//Generate the ID guid - Remove this when EF Core supports ValueObjects
// https://github.com/aspnet/EntityFramework/issues/246
this.Id = Guid.NewGuid();
this.Street = street;
this.City = city;
this.State = state;
this.StateCode = stateCode;
this.Country = country;
this.CountryCode = countryCode;
this.ZipCode = zipCode;
this.Latitude = latitude;
this.Longitude = longitude;
}
//Infrastructure requisite - Parameterless constructor needed by EF
Address() { }
public virtual String Street { get; private set; }
public virtual String City { get; private set; }
public virtual String State { get; private set; }
public virtual String StateCode { get; private set; }
public virtual String Country { get; private set; }
public virtual String CountryCode { get; private set; }
public virtual String ZipCode { get; private set; }
public virtual double Latitude { get; private set; }
public virtual double Longitude { get; private set; }
}
}

+ 0
- 112
src/Services/Ordering/Ordering.Domain/AggregatesModel/Order/Order.cs View File

@ -1,112 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.eShopOnContainers.Services.Ordering.Domain.SeedWork;
namespace Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel
{
public class Order : Entity, IAggregateRoot
{
public Order(Guid buyerId, Address shippingAddress, Address billingAddress)
: this(buyerId, shippingAddress, billingAddress, DateTime.UtcNow)
{
}
public Order(Guid buyerId, Address shippingAddress, Address billingAddress, DateTime orderDate)
{
this.BuyerId = buyerId;
this.ShippingAddress = shippingAddress;
this.BillingAddress = billingAddress;
this.OrderDate = orderDate;
this.Status = OrderStatus.New;
}
//Infrastructure requisite - Parameterless constructor needed by EF
Order() { }
//Order ID comes derived from the Entity base class
List<OrderItem> _orderItems;
public virtual List<OrderItem> OrderItems
{
get
{
if (_orderItems == null)
_orderItems = new List<OrderItem>();
return _orderItems;
}
private set
{
_orderItems = value;
}
}
public string OrderNumber
{
get
{
return string.Format("{0}/{1}-{2}", OrderDate.Year, OrderDate.Month, SequenceNumber);
}
}
public int SequenceNumber { get; set; }
public virtual Guid BuyerId { get; private set; }
public virtual Address ShippingAddress { get; private set; }
public virtual Address BillingAddress { get; private set; }
public virtual DateTime OrderDate { get; private set; }
public virtual OrderStatus Status { get; private set; }
////////////////////////////////////////////////////////////////////////////////////////
//Domain Rules and Logic in Order Aggregate-Root (Sample of a "NO ANEMIC DOMAIN MODEL" )
////////////////////////////////////////////////////////////////////////////////////////
public OrderItem AddNewOrderItem(Guid productId, int quantity, decimal unitPrice, decimal discount)
{
//check preconditions
if (productId == Guid.Empty)
throw new ArgumentNullException("productId");
if (quantity <= 0)
{
throw new ArgumentException("The quantity of Product in an Order cannot be equal or less than cero");
}
//check discount values
if (discount < 0)
discount = 0;
if (discount > 100)
discount = 100;
//create new order line
var newOrderItem = new OrderItem()
{
OrderId = this.Id,
ProductId = productId,
Quantity = quantity,
FulfillmentRemaining = quantity,
Discount = discount,
UnitPrice = unitPrice
};
//set identity
newOrderItem.GenerateNewIdentity();
//add order item
this.OrderItems.Add(newOrderItem);
//return added orderline
return newOrderItem;
}
}
}

+ 0
- 33
src/Services/Ordering/Ordering.Domain/AggregatesModel/Order/OrderItem.cs View File

@ -1,33 +0,0 @@
using System;
using System.Runtime.Serialization;
using Microsoft.eShopOnContainers.Services.Ordering.Domain.SeedWork;
namespace Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel
{
public class OrderItem : Entity
{
public OrderItem() { } // Infrastructure. EF might need a plain constructor. Do not use.
//NOTE: The OrderItem Id (Id) comes from the Entity base class
public Guid ProductId { get; set; }
public Guid OrderId { get; set; }
public decimal UnitPrice { get; set; }
public string ProductName { get; set; }
public int Quantity { get; set; }
public decimal Discount { get; set; }
public int FulfillmentRemaining { get; set; }
public override string ToString()
{
return String.Format("Product Id: {0}, Quantity: {1}, Fulfillment Remaing: {2}", this.Id, this.Quantity, this.FulfillmentRemaining);
}
}
}

+ 0
- 18
src/Services/Ordering/Ordering.Domain/AggregatesModel/Order/OrderStatus.cs View File

@ -1,18 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel
{
public enum OrderStatus
{
Unknown,
New,
Submitted,
InProcess,
Backordered,
Shipped,
Canceled,
}
}

+ 12
- 0
src/Services/Ordering/Ordering.Domain/Buyer.cs View File

@ -0,0 +1,12 @@
namespace Microsoft.eShopOnContainers.Services.Ordering.Domain
{
using Microsoft.eShopOnContainers.Services.Ordering.Domain.SeedWork;
public class Buyer
:Entity,IAggregateRoot
{
public string FullName { get; private set; }
protected Buyer() { }
}
}

+ 0
- 15
src/Services/Ordering/Ordering.Domain/Contracts/IBuyerRepository.cs View File

@ -1,15 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel;
using Microsoft.eShopOnContainers.Services.Ordering.Domain.SeedWork;
namespace Microsoft.eShopOnContainers.Services.Ordering.Domain.Contracts
{
public interface IBuyerRepository : IRepository
{
//TBD - To define Specific Actions Not In Base Repo
}
}

+ 0
- 20
src/Services/Ordering/Ordering.Domain/Contracts/IOrderRepository.cs View File

@ -1,20 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel;
using Microsoft.eShopOnContainers.Services.Ordering.Domain.SeedWork;
namespace Microsoft.eShopOnContainers.Services.Ordering.Domain.Contracts
{
public interface IOrderRepository : IRepository
{
void Add(Order order);
void Update(Order order);
Task Remove(Guid id);
Task<Order> FindAsync(Guid id);
}
}

+ 30
- 0
src/Services/Ordering/Ordering.Domain/Order.cs View File

@ -0,0 +1,30 @@
namespace Microsoft.eShopOnContainers.Services.Ordering.Domain
{
using Microsoft.eShopOnContainers.Services.Ordering.Domain.SeedWork;
using System;
using System.Collections.Generic;
public class Order
:Entity, IAggregateRoot
{
public int BuyerId { get; private set; }
public Buyer Buyer { get; private set; }
public DateTime OrderDate { get; private set; }
public OrderStatus Status { get; private set; }
public ICollection<OrderItem> OrderItems { get; set; }
public int ShippingAddressId { get; private set; }
public Address ShippingAddress { get; private set; }
public int BillingAddressId { get; private set; }
public Address BillingAddress { get; private set; }
protected Order() { }
}
}

+ 25
- 0
src/Services/Ordering/Ordering.Domain/OrderItem.cs View File

@ -0,0 +1,25 @@
namespace Microsoft.eShopOnContainers.Services.Ordering.Domain
{
using Microsoft.eShopOnContainers.Services.Ordering.Domain.SeedWork;
public class OrderItem
:Entity
{
public int ProductId { get; private set; }
public string ProductName { get; private set; }
public int OrderId { get; private set; }
public decimal UnitPrice { get; private set; }
public decimal Discount { get; private set; }
public int Units { get; private set; }
protected OrderItem()
{
}
}
}

+ 59
- 0
src/Services/Ordering/Ordering.Domain/OrderStatus.cs View File

@ -0,0 +1,59 @@
namespace Microsoft.eShopOnContainers.Services.Ordering.Domain
{
using SeedWork;
using System;
using System.Collections.Generic;
using System.Linq;
public class OrderStatus
:Entity
{
public string Name { get; private set; }
public static OrderStatus New = new OrderStatus(1, nameof(New).ToLowerInvariant());
public static OrderStatus Submitted = new OrderStatus(1, nameof(Submitted).ToLowerInvariant());
public static OrderStatus InProcess = new OrderStatus(1, nameof(InProcess).ToLowerInvariant());
public static OrderStatus Shipped = new OrderStatus(1, nameof(Shipped).ToLowerInvariant());
public static OrderStatus Canceled = new OrderStatus(1, nameof(Canceled).ToLowerInvariant());
protected OrderStatus()
{
}
public OrderStatus(int id, string name)
{
Id = id;
Name = name;
}
public static IEnumerable<OrderStatus> List()
{
return new[] { New, Submitted, InProcess, Shipped, Canceled };
}
public static OrderStatus FromName(string name)
{
var state = List()
.SingleOrDefault(s => String.Equals(s.Name, name, StringComparison.CurrentCultureIgnoreCase));
if (state == null)
{
throw new ArgumentException($"Possible values for OrderStatus: {String.Join(",", List().Select(s => s.Name))}");
}
return state;
}
public static OrderStatus From(int id)
{
var state = List().SingleOrDefault(s => s.Id == id);
if (state == null)
{
throw new ArgumentException($"Possible values for OrderStatus: {String.Join(",", List().Select(s => s.Name))}");
}
return state;
}
}
}

+ 8
- 66
src/Services/Ordering/Ordering.Domain/SeedWork/Entity.cs View File

@ -1,24 +1,15 @@
using System;
namespace Microsoft.eShopOnContainers.Services.Ordering.Domain.SeedWork
namespace Microsoft.eShopOnContainers.Services.Ordering.Domain.SeedWork
{
/// <summary>
/// Base class for entities
/// </summary>
using System;
public abstract class Entity
{
//Members
int? _requestedHashCode;
Guid _Id;
int _Id;
//Properties
/// <summary>
/// Get the persisten object identifier
/// </summary>
public virtual Guid Id
public virtual int Id
{
get
{
@ -30,44 +21,11 @@ namespace Microsoft.eShopOnContainers.Services.Ordering.Domain.SeedWork
}
}
//Public Methods
/// <summary>
/// Check if this entity is transient, ie, without identity at this moment
/// </summary>
/// <returns>True if entity is transient, else false</returns>
public bool IsTransient()
{
return this.Id == Guid.Empty;
}
/// <summary>
/// Generate identity for this entity
/// </summary>
public void GenerateNewIdentity()
{
if ( IsTransient())
this.Id = IdentityGenerator.NewSequentialGuid();
}
/// <summary>
/// Change current identity for a new non transient identity
/// </summary>
/// <param name="identity">the new identity</param>
public void ChangeCurrentIdentity(Guid identity)
{
if ( identity != Guid.Empty)
this.Id = identity;
return this.Id == default(Int32);
}
//Overrides Methods
/// <summary>
/// <see cref="M:System.Object.Equals"/>
/// </summary>
/// <param name="obj"><see cref="M:System.Object.Equals"/></param>
/// <returns><see cref="M:System.Object.Equals"/></returns>
public override bool Equals(object obj)
{
if (obj == null || !(obj is Entity))
@ -84,10 +42,6 @@ namespace Microsoft.eShopOnContainers.Services.Ordering.Domain.SeedWork
return item.Id == this.Id;
}
/// <summary>
/// <see cref="M:System.Object.GetHashCode"/>
/// </summary>
/// <returns><see cref="M:System.Object.GetHashCode"/></returns>
public override int GetHashCode()
{
if (!IsTransient())
@ -101,12 +55,7 @@ namespace Microsoft.eShopOnContainers.Services.Ordering.Domain.SeedWork
return base.GetHashCode();
}
/// <summary>
/// equals operator
/// </summary>
/// <param name="left">left parameter</param>
/// <param name="right">right parameter</param>
/// <returns>true if equals</returns>
public static bool operator ==(Entity left, Entity right)
{
if (Object.Equals(left, null))
@ -115,16 +64,9 @@ namespace Microsoft.eShopOnContainers.Services.Ordering.Domain.SeedWork
return left.Equals(right);
}
/// <summary>
/// Distinct operator
/// </summary>
/// <param name="left">left parameter</param>
/// <param name="right">right parameter</param>
/// <returns>True if different</returns>
public static bool operator !=(Entity left, Entity right)
{
return !(left == right);
}
}
}

+ 0
- 47
src/Services/Ordering/Ordering.Domain/SeedWork/IdentityGenerator.cs View File

@ -1,47 +0,0 @@
using System;
namespace Microsoft.eShopOnContainers.Services.Ordering.Domain.SeedWork
{
internal static class IdentityGenerator
{
/// <summary>
/// This algorithm generates secuential GUIDs across system boundaries, ideal for databases
/// </summary>
/// <returns></returns>
public static Guid NewSequentialGuid()
{
byte[] uid = Guid.NewGuid().ToByteArray();
byte[] binDate = BitConverter.GetBytes(DateTime.UtcNow.Ticks);
byte[] secuentialGuid = new byte[uid.Length];
secuentialGuid[0] = uid[0];
secuentialGuid[1] = uid[1];
secuentialGuid[2] = uid[2];
secuentialGuid[3] = uid[3];
secuentialGuid[4] = uid[4];
secuentialGuid[5] = uid[5];
secuentialGuid[6] = uid[6];
// set the first part of the 8th byte to '1100' so
// later we'll be able to validate it was generated by us
secuentialGuid[7] = (byte)(0xc0 | (0xf & uid[7]));
// the last 8 bytes are sequential,
// it minimizes index fragmentation
// to a degree as long as there are not a large
// number of Secuential-Guids generated per millisecond
secuentialGuid[9] = binDate[0];
secuentialGuid[8] = binDate[1];
secuentialGuid[15] = binDate[2];
secuentialGuid[14] = binDate[3];
secuentialGuid[13] = binDate[4];
secuentialGuid[12] = binDate[5];
secuentialGuid[11] = binDate[6];
secuentialGuid[10] = binDate[7];
return new Guid(secuentialGuid);
}
}
}

+ 13
- 37
src/Services/Ordering/Ordering.Domain/SeedWork/ValueObject.cs View File

@ -1,16 +1,13 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Reflection;

namespace Microsoft.eShopOnContainers.Services.Ordering.Domain.SeedWork
{
/// <summary>
/// Base class for value objects in domain.
/// Value
/// </summary>
/// <typeparam name="TValueObject">The type of this value object</typeparam>
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Reflection;
public class ValueObject<TValueObject> : IEquatable<TValueObject>
where TValueObject : ValueObject<TValueObject>
{
@ -22,11 +19,7 @@ namespace Microsoft.eShopOnContainers.Services.Ordering.Domain.SeedWork
//IEquatable and Override Equals operators
/// <summary>
/// <see cref="M:System.Object.IEquatable{TValueObject}"/>
/// </summary>
/// <param name="other"><see cref="M:System.Object.IEquatable{TValueObject}"/></param>
/// <returns><see cref="M:System.Object.IEquatable{TValueObject}"/></returns>
public bool Equals(TValueObject other)
{
if ((object)other == null)
@ -62,11 +55,7 @@ namespace Microsoft.eShopOnContainers.Services.Ordering.Domain.SeedWork
else
return true;
}
/// <summary>
/// <see cref="M:System.Object.Equals"/>
/// </summary>
/// <param name="obj"><see cref="M:System.Object.Equals"/></param>
/// <returns><see cref="M:System.Object.Equals"/></returns>
public override bool Equals(object obj)
{
if ((object)obj == null)
@ -83,10 +72,7 @@ namespace Microsoft.eShopOnContainers.Services.Ordering.Domain.SeedWork
return false;
}
/// <summary>
/// <see cref="M:System.Object.GetHashCode"/>
/// </summary>
/// <returns><see cref="M:System.Object.GetHashCode"/></returns>
public override int GetHashCode()
{
int hashCode = 31;
@ -119,12 +105,7 @@ namespace Microsoft.eShopOnContainers.Services.Ordering.Domain.SeedWork
return hashCode;
}
/// <summary>
///
/// </summary>
/// <param name="left"></param>
/// <param name="right"></param>
/// <returns></returns>
public static bool operator ==(ValueObject<TValueObject> left, ValueObject<TValueObject> right)
{
if (Object.Equals(left, null))
@ -133,12 +114,7 @@ namespace Microsoft.eShopOnContainers.Services.Ordering.Domain.SeedWork
return left.Equals(right);
}
/// <summary>
///
/// </summary>
/// <param name="left"></param>
/// <param name="right"></param>
/// <returns></returns>
public static bool operator !=(ValueObject<TValueObject> left, ValueObject<TValueObject> right)
{
return !(left == right);


+ 0
- 24
src/Services/Ordering/Ordering.SqlData/Queries/IOrderdingQueries.cs View File

@ -1,24 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Microsoft.eShopOnContainers.Services.Ordering.SqlData.Queries
{
//The OrderingQueries Contracts/Interfaces could be moved to a third assembly
//We're not putting this contract in the Domain layer assembly because
//queries/joins are just Application's needs and should not be limited
//to the Domain Model restrictions (Aggregates and Repositories restrictions).
//
//In this case we're using the same EF Context but another good approach
//is also to simply use SQL sentences for the queries with any Micro-ORM (like Dapper) or even just ADO.NET
//
//The point is that Queries are IDEMPOTENT and don't need to commit to DDD Domain restrictions
//so could be implemented in a completely orthogonal way in regards the Domain Layer (à la CQRS)
public interface IOrderdingQueries
{
Task<dynamic> GetAllOrdersIncludingValueObjectsAndChildEntities();
Task<dynamic> GetOrderById(Guid orderId);
}
}

+ 0
- 98
src/Services/Ordering/Ordering.SqlData/Queries/OrderingQueries.cs View File

@ -1,98 +0,0 @@

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
using Microsoft.eShopOnContainers.Services.Ordering.SqlData.UnitOfWork;
using Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel;
using Microsoft.eShopOnContainers.Services.Ordering.SqlData.Queries;
namespace Microsoft.eShopOnContainers.Services.Ordering.SqlData.Queries
{
//In this case, for the Application queries, we're using the same EF Context but another good approach
//is also to simply use SQL sentences for the queries with any Micro-ORM (like Dapper) or even just ADO.NET
//
//The point is that Queries are IDEMPOTENT and don't need to commit to DDD Domain restrictions
//so could be implemented in a completely orthogonal way in regards the Domain Layer (à la CQRS)
public class OrderingQueries : IOrderdingQueries
{
private OrderingDbContext _dbContext;
public OrderingQueries(OrderingDbContext orderingDbContext)
{
_dbContext = orderingDbContext;
}
public async Task<dynamic> GetAllOrdersIncludingValueObjectsAndChildEntities()
{
var orders = await _dbContext.Orders
.Include(o => o.ShippingAddress)
.Include(o => o.BillingAddress)
.Include(o => o.OrderItems)
.ToListAsync<Order>();
// Dynamically generated a Response-Model that includes only the fields you need in the response.
// This keeps the JSON response minimal.
// Could also use var
dynamic response = orders.Select(o => new
{
id = o.Id,
orderNumber = o.OrderNumber,
buyerId = o.BuyerId,
orderDate = o.OrderDate,
status = o.Status,
shippingAddress = o.ShippingAddress,
billingAddress = o.BillingAddress,
orderItems = o.OrderItems.Select(i => new
{
id = i.Id,
productId = i.ProductId,
unitPrice = i.UnitPrice,
quantity = i.Quantity,
discount = i.Discount
}
)
});
return response;
}
public async Task<dynamic> GetOrderById(Guid orderId)
{
var order = await _dbContext.Orders
.Include(o => o.ShippingAddress)
.Include(o => o.BillingAddress)
.Include(o => o.OrderItems)
.Where(o => o.Id == orderId)
.SingleOrDefaultAsync<Order>();
// Dynamically generated a Response-Model that includes only the fields you need in the response.
// This keeps the JSON response minimal.
// Could also use var
dynamic response = new
{
id = order.Id,
orderNumber = order.OrderNumber,
buyerId = order.BuyerId,
orderDate = order.OrderDate,
status = order.Status,
shippingAddress = order.ShippingAddress,
billingAddress = order.BillingAddress,
orderItems = order.OrderItems.Select(i => new
{
id = i.Id,
productId = i.ProductId,
unitPrice = i.UnitPrice,
quantity = i.Quantity,
discount = i.Discount
}
)
};
return response;
}
}
}

+ 0
- 51
src/Services/Ordering/Ordering.SqlData/Repositories/OrderRepository.cs View File

@ -1,51 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel;
using Microsoft.eShopOnContainers.Services.Ordering.Domain.Contracts;
using Microsoft.eShopOnContainers.Services.Ordering.SqlData.UnitOfWork;
using Microsoft.eShopOnContainers.Services.Ordering.Domain.SeedWork;
using Microsoft.EntityFrameworkCore;
namespace Microsoft.eShopOnContainers.Services.Ordering.SqlData.Repositories
{
//1:1 relationship between Repository and Aggregate (i.e. OrderRepository and Order)
public class OrderRepository : IOrderRepository
{
private readonly OrderingDbContext _context;
public IUnitOfWork UnitOfWork => _context;
public OrderRepository(OrderingDbContext orderingDbContext)
{
_context = orderingDbContext;
}
public void Add(Order order)
{
_context.Orders.Add(order);
}
public void Update(Order order)
{
_context.Orders.Update(order);
}
public async Task Remove(Guid orderId)
{
var orderToRemove = await _context.Orders.Where(o => o.Id == orderId).SingleOrDefaultAsync();
_context.Orders.Remove(orderToRemove);
}
public async Task<Order> FindAsync(Guid id)
{
if (id != Guid.Empty)
return await _context.Set<Order>().FirstOrDefaultAsync(o => o.Id == id);
else
return null;
}
}
}

Loading…
Cancel
Save