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
This commit is contained in:
commit
decb87e0c6
@ -47,7 +47,7 @@ Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "UnitTest", "test\Services\U
|
|||||||
EndProject
|
EndProject
|
||||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Identity", "Identity", "{24CD3B53-141E-4A07-9B0D-796641E1CF78}"
|
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Identity", "Identity", "{24CD3B53-141E-4A07-9B0D-796641E1CF78}"
|
||||||
EndProject
|
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
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
|
@ -8,7 +8,7 @@ using Microsoft.AspNetCore.Authorization;
|
|||||||
|
|
||||||
namespace Microsoft.eShopOnContainers.Services.Basket.API.Controllers
|
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.
|
//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,
|
//If this is the case we should also investigate changing the serialization format used for Redis,
|
||||||
//using a HashSet instead of a simple string.
|
//using a HashSet instead of a simple string.
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
FROM microsoft/aspnetcore:1.0.1
|
FROM microsoft/aspnetcore:1.1
|
||||||
ENTRYPOINT ["dotnet", "Basket.API.dll"]
|
ENTRYPOINT ["dotnet", "Basket.API.dll"]
|
||||||
ARG source=.
|
ARG source=.
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
|
@ -18,7 +18,7 @@ namespace Microsoft.eShopOnContainers.Services.Basket.API.Model
|
|||||||
private ConnectionMultiplexer _redis;
|
private ConnectionMultiplexer _redis;
|
||||||
|
|
||||||
|
|
||||||
public RedisBasketRepository(IOptions<BasketSettings> options, ILoggerFactory loggerFactory)
|
public RedisBasketRepository(IOptionsSnapshot<BasketSettings> options, ILoggerFactory loggerFactory)
|
||||||
{
|
{
|
||||||
_settings = options.Value;
|
_settings = options.Value;
|
||||||
_logger = loggerFactory.CreateLogger<RedisBasketRepository>();
|
_logger = loggerFactory.CreateLogger<RedisBasketRepository>();
|
||||||
|
@ -44,7 +44,7 @@ namespace Microsoft.eShopOnContainers.Services.Basket.API
|
|||||||
//that cost to startup instead of having the first request pay the
|
//that cost to startup instead of having the first request pay the
|
||||||
//penalty.
|
//penalty.
|
||||||
services.AddSingleton<ConnectionMultiplexer>((sp) => {
|
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;
|
var ips = Dns.GetHostAddressesAsync(config.ConnectionString).Result;
|
||||||
return ConnectionMultiplexer.Connect(ips.First().ToString());
|
return ConnectionMultiplexer.Connect(ips.First().ToString());
|
||||||
});
|
});
|
||||||
|
@ -1,20 +1,20 @@
|
|||||||
{
|
{
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"Microsoft.NETCore.App": {
|
"Microsoft.NETCore.App": {
|
||||||
"version": "1.0.0",
|
"version": "1.1.0",
|
||||||
"type": "platform"
|
"type": "platform"
|
||||||
},
|
},
|
||||||
"System.Threading": "4.0.11",
|
"System.Threading": "4.3.0",
|
||||||
"Microsoft.AspNetCore.Mvc": "1.0.0",
|
"Microsoft.AspNetCore.Mvc": "1.1.0",
|
||||||
"Microsoft.AspNetCore.Server.IISIntegration": "1.0.0",
|
"Microsoft.AspNetCore.Server.IISIntegration": "1.1.0",
|
||||||
"Microsoft.AspNetCore.Server.Kestrel": "1.0.0",
|
"Microsoft.AspNetCore.Server.Kestrel": "1.1.0",
|
||||||
"Microsoft.Extensions.Configuration.EnvironmentVariables": "1.0.0",
|
"Microsoft.Extensions.Configuration.EnvironmentVariables": "1.1.0",
|
||||||
"Microsoft.Extensions.Configuration.FileExtensions": "1.0.0",
|
"Microsoft.Extensions.Configuration.FileExtensions": "1.1.0",
|
||||||
"Microsoft.Extensions.Configuration.Json": "1.0.0",
|
"Microsoft.Extensions.Configuration.Json": "1.1.0",
|
||||||
"Microsoft.Extensions.Logging": "1.0.0",
|
"Microsoft.Extensions.Logging": "1.1.0",
|
||||||
"Microsoft.Extensions.Logging.Console": "1.0.0",
|
"Microsoft.Extensions.Logging.Console": "1.1.0",
|
||||||
"Microsoft.Extensions.Logging.Debug": "1.0.0",
|
"Microsoft.Extensions.Logging.Debug": "1.1.0",
|
||||||
"Microsoft.Extensions.Options.ConfigurationExtensions": "1.0.0",
|
"Microsoft.Extensions.Options.ConfigurationExtensions": "1.1.0",
|
||||||
"StackExchange.Redis": "1.1.608",
|
"StackExchange.Redis": "1.1.608",
|
||||||
"Newtonsoft.Json": "9.0.1",
|
"Newtonsoft.Json": "9.0.1",
|
||||||
"IdentityServer4.AccessTokenValidation": "1.0.1-rc3",
|
"IdentityServer4.AccessTokenValidation": "1.0.1-rc3",
|
||||||
@ -24,10 +24,11 @@
|
|||||||
"Microsoft.AspNetCore.Server.IISIntegration.Tools": "1.0.0-preview2-final"
|
"Microsoft.AspNetCore.Server.IISIntegration.Tools": "1.0.0-preview2-final"
|
||||||
},
|
},
|
||||||
"frameworks": {
|
"frameworks": {
|
||||||
"netcoreapp1.0": {
|
"netcoreapp1.1": {
|
||||||
"imports": [
|
"imports": [
|
||||||
"dotnet5.6",
|
"netstandard1.6.1",
|
||||||
"portable-net45+win8"
|
"dnxcore50",
|
||||||
|
"portable-net451+win8"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -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
|
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]")]
|
[Route("api/v1/[controller]")]
|
||||||
public class CatalogController : ControllerBase
|
public class CatalogController : ControllerBase
|
||||||
{
|
{
|
||||||
private readonly CatalogContext _context;
|
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;
|
_context = context;
|
||||||
_settings = settings;
|
_settings = settings;
|
||||||
|
|
||||||
|
((DbContext)context).ChangeTracker.QueryTrackingBehavior = QueryTrackingBehavior.NoTracking;
|
||||||
}
|
}
|
||||||
|
|
||||||
// GET api/v1/[controller]/items/[?pageSize=3&pageIndex=10]
|
// 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)
|
public async Task<IActionResult> Items(int pageSize = 10, int pageIndex = 0)
|
||||||
{
|
{
|
||||||
var totalItems = await _context.CatalogItems
|
var totalItems = await _context.CatalogItems
|
||||||
.LongCountAsync();
|
.LongCountAsync();
|
||||||
|
|
||||||
var itemsOnPage = await _context.CatalogItems
|
var itemsOnPage = await _context.CatalogItems
|
||||||
.OrderBy(c=>c.Name)
|
.OrderBy(c=>c.Name)
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
FROM microsoft/aspnetcore:1.0.1
|
FROM microsoft/aspnetcore:1.1
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
EXPOSE 80
|
EXPOSE 80
|
||||||
COPY . /app
|
COPY . /app
|
||||||
|
@ -38,8 +38,6 @@
|
|||||||
|
|
||||||
public void ConfigureServices(IServiceCollection services)
|
public void ConfigureServices(IServiceCollection services)
|
||||||
{
|
{
|
||||||
services.AddSingleton<IConfiguration>(Configuration);
|
|
||||||
|
|
||||||
services.AddDbContext<CatalogContext>(c =>
|
services.AddDbContext<CatalogContext>(c =>
|
||||||
{
|
{
|
||||||
c.UseSqlServer(Configuration["ConnectionString"]);
|
c.UseSqlServer(Configuration["ConnectionString"]);
|
||||||
|
@ -1,47 +1,39 @@
|
|||||||
{
|
{
|
||||||
"dependencies": {
|
|
||||||
"Microsoft.NETCore.App": {
|
|
||||||
"version": "1.0.1",
|
|
||||||
"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",
|
|
||||||
"Swashbuckle": "6.0.0-beta902"
|
|
||||||
},
|
|
||||||
"tools": {
|
|
||||||
"Microsoft.EntityFrameworkCore.Tools": "1.0.0-preview2-final"
|
|
||||||
},
|
|
||||||
"frameworks": {
|
|
||||||
"netcoreapp1.0": {
|
|
||||||
"imports": [
|
|
||||||
"dotnet5.6",
|
|
||||||
"portable-net45+win8"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"buildOptions": {
|
"buildOptions": {
|
||||||
"emitEntryPoint": true,
|
"emitEntryPoint": true,
|
||||||
"preserveCompilationContext": true,
|
"preserveCompilationContext": true,
|
||||||
"debugType": "portable"
|
"debugType": "portable"
|
||||||
},
|
},
|
||||||
"runtimeOptions": {
|
"dependencies": {
|
||||||
"configProperties": {
|
"Microsoft.NETCore.App": {
|
||||||
"System.GC.Server": true
|
"version": "1.1.0",
|
||||||
|
"type": "platform"
|
||||||
|
},
|
||||||
|
"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"
|
||||||
|
},
|
||||||
|
"frameworks": {
|
||||||
|
"netcoreapp1.1": {
|
||||||
|
"imports": [
|
||||||
|
"dotnet5.6",
|
||||||
|
"portable-net45+win8"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"publishOptions": {
|
"publishOptions": {
|
||||||
@ -56,6 +48,14 @@
|
|||||||
"Dockerfile"
|
"Dockerfile"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
"runtimeOptions": {
|
||||||
|
"configProperties": {
|
||||||
|
"System.GC.Server": true
|
||||||
|
}
|
||||||
|
},
|
||||||
"scripts": {},
|
"scripts": {},
|
||||||
|
"tools": {
|
||||||
|
"Microsoft.EntityFrameworkCore.Tools": "1.1.0-preview4-final"
|
||||||
|
},
|
||||||
"userSecretsId": "aspnet-Catalog.API-20161122013618"
|
"userSecretsId": "aspnet-Catalog.API-20161122013618"
|
||||||
}
|
}
|
@ -15,10 +15,10 @@ namespace IdentityServer4.Quickstart.UI.Controllers
|
|||||||
public class HomeController : Controller
|
public class HomeController : Controller
|
||||||
{
|
{
|
||||||
private readonly IIdentityServerInteractionService _interaction;
|
private readonly IIdentityServerInteractionService _interaction;
|
||||||
private readonly IOptions<AppSettings> _settings;
|
private readonly IOptionsSnapshot<AppSettings> _settings;
|
||||||
private readonly IRedirectService _redirectSvc;
|
private readonly IRedirectService _redirectSvc;
|
||||||
|
|
||||||
public HomeController(IIdentityServerInteractionService interaction, IOptions<AppSettings> settings,IRedirectService redirectSvc)
|
public HomeController(IIdentityServerInteractionService interaction, IOptionsSnapshot<AppSettings> settings,IRedirectService redirectSvc)
|
||||||
{
|
{
|
||||||
_interaction = interaction;
|
_interaction = interaction;
|
||||||
_settings = settings;
|
_settings = settings;
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
FROM microsoft/aspnetcore:1.0.1
|
FROM microsoft/aspnetcore:1.1
|
||||||
ENTRYPOINT ["dotnet", "Identity.API.dll"]
|
ENTRYPOINT ["dotnet", "Identity.API.dll"]
|
||||||
ARG source=.
|
ARG source=.
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
|
@ -3,59 +3,55 @@
|
|||||||
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"Microsoft.NETCore.App": {
|
"Microsoft.NETCore.App": {
|
||||||
"version": "1.0.1",
|
"version": "1.1.0",
|
||||||
"type": "platform"
|
"type": "platform"
|
||||||
},
|
},
|
||||||
"Microsoft.AspNetCore.Authentication.Cookies": "1.0.0",
|
"Microsoft.AspNetCore.Authentication.Cookies": "1.1.0",
|
||||||
"Microsoft.AspNetCore.Diagnostics": "1.0.0",
|
"Microsoft.AspNetCore.Diagnostics": "1.1.0",
|
||||||
"Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore": "1.0.0",
|
"Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore": "1.1.0",
|
||||||
"Microsoft.AspNetCore.Identity.EntityFrameworkCore": "1.0.0",
|
"Microsoft.AspNetCore.Identity.EntityFrameworkCore": "1.1.0",
|
||||||
"Microsoft.AspNetCore.Mvc": "1.0.1",
|
"Microsoft.AspNetCore.Mvc": "1.1.0",
|
||||||
"Microsoft.AspNetCore.Razor.Tools": {
|
"Microsoft.AspNetCore.Routing": "1.1.0",
|
||||||
"version": "1.0.0-preview2-final",
|
"Microsoft.AspNetCore.Server.IISIntegration": "1.1.0",
|
||||||
"type": "build"
|
"Microsoft.AspNetCore.Server.Kestrel": "1.1.0",
|
||||||
},
|
"Microsoft.AspNetCore.StaticFiles": "1.1.0",
|
||||||
"Microsoft.AspNetCore.Routing": "1.0.1",
|
"Microsoft.EntityFrameworkCore.SqlServer": "1.1.0",
|
||||||
"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.EntityFrameworkCore.SqlServer.Design": {
|
"Microsoft.EntityFrameworkCore.SqlServer.Design": {
|
||||||
"version": "1.0.1",
|
"version": "1.1.0",
|
||||||
"type": "build"
|
"type": "build"
|
||||||
},
|
},
|
||||||
"Microsoft.EntityFrameworkCore.Tools": {
|
"Microsoft.EntityFrameworkCore.Tools": {
|
||||||
"version": "1.0.0-preview2-final",
|
"version": "1.1.0-preview4-final",
|
||||||
"type": "build"
|
"type": "build"
|
||||||
},
|
},
|
||||||
"Microsoft.Extensions.Configuration.EnvironmentVariables": "1.0.0",
|
"Microsoft.Extensions.Configuration.EnvironmentVariables": "1.1.0",
|
||||||
"Microsoft.Extensions.Configuration.Json": "1.0.0",
|
"Microsoft.Extensions.Configuration.Json": "1.1.0",
|
||||||
"Microsoft.Extensions.Configuration.UserSecrets": "1.0.0",
|
"Microsoft.Extensions.Configuration.UserSecrets": "1.1.0",
|
||||||
"Microsoft.Extensions.Logging": "1.0.0",
|
"Microsoft.Extensions.Logging": "1.1.0",
|
||||||
"Microsoft.Extensions.Logging.Console": "1.0.0",
|
"Microsoft.Extensions.Logging.Console": "1.1.0",
|
||||||
"Microsoft.Extensions.Logging.Debug": "1.0.0",
|
"Microsoft.Extensions.Logging.Debug": "1.1.0",
|
||||||
"Microsoft.Extensions.Options.ConfigurationExtensions": "1.0.0",
|
"Microsoft.Extensions.Options.ConfigurationExtensions": "1.1.0",
|
||||||
"Microsoft.VisualStudio.Web.BrowserLink.Loader": "14.0.0",
|
"Microsoft.VisualStudio.Web.BrowserLink.Loader": "14.1.0",
|
||||||
"Microsoft.VisualStudio.Web.CodeGeneration.Tools": {
|
"Microsoft.VisualStudio.Web.CodeGeneration.Tools": {
|
||||||
"version": "1.0.0-preview2-final",
|
"version": "1.1.0-preview4-final",
|
||||||
"type": "build"
|
"type": "build"
|
||||||
},
|
},
|
||||||
"Microsoft.VisualStudio.Web.CodeGenerators.Mvc": {
|
"Microsoft.VisualStudio.Web.CodeGenerators.Mvc": {
|
||||||
"version": "1.0.0-preview2-final",
|
"version": "1.1.0-preview4-final",
|
||||||
"type": "build"
|
"type": "build"
|
||||||
},
|
},
|
||||||
"IdentityServer4.AspNetIdentity": "1.0.0-rc3",
|
"IdentityServer4.AspNetIdentity": "1.0.0-rc3",
|
||||||
"IdentityServer4.EntityFramework": "1.0.0-rc3"
|
"IdentityServer4.EntityFramework": "1.0.0-rc3",
|
||||||
},
|
},
|
||||||
|
|
||||||
"tools": {
|
"tools": {
|
||||||
"BundlerMinifier.Core": "2.0.238",
|
"BundlerMinifier.Core": "2.0.238",
|
||||||
"Microsoft.AspNetCore.Razor.Tools": "1.0.0-preview2-final",
|
"Microsoft.AspNetCore.Razor.Tools": "1.1.0-preview4-final",
|
||||||
"Microsoft.AspNetCore.Server.IISIntegration.Tools": "1.0.0-preview2-final",
|
"Microsoft.AspNetCore.Server.IISIntegration.Tools": "1.1.0-preview4-final",
|
||||||
"Microsoft.EntityFrameworkCore.Tools": "1.0.0-preview2-final",
|
"Microsoft.EntityFrameworkCore.Tools": "1.1.0-preview4-final",
|
||||||
"Microsoft.Extensions.SecretManager.Tools": "1.0.0-preview2-final",
|
"Microsoft.Extensions.SecretManager.Tools": "1.1.0-preview4-final",
|
||||||
"Microsoft.VisualStudio.Web.CodeGeneration.Tools": {
|
"Microsoft.VisualStudio.Web.CodeGeneration.Tools": {
|
||||||
"version": "1.0.0-preview2-final",
|
"version": "1.1.0-preview4-final",
|
||||||
"imports": [
|
"imports": [
|
||||||
"portable-net45+win8"
|
"portable-net45+win8"
|
||||||
]
|
]
|
||||||
|
@ -31,7 +31,7 @@ namespace Microsoft.eShopOnContainers.Services.Ordering.API.Application.Commands
|
|||||||
|
|
||||||
public int CardTypeId { get; set; }
|
public int CardTypeId { get; set; }
|
||||||
|
|
||||||
public string BuyerFullName { get; set; }
|
public string BuyerIdentityGuid { get; set; }
|
||||||
|
|
||||||
public IEnumerable<OrderItemDTO> OrderItems => _orderItems;
|
public IEnumerable<OrderItemDTO> OrderItems => _orderItems;
|
||||||
|
|
||||||
|
@ -12,6 +12,7 @@
|
|||||||
private readonly IBuyerRepository _buyerRepository;
|
private readonly IBuyerRepository _buyerRepository;
|
||||||
private readonly IOrderRepository _orderRepository;
|
private readonly IOrderRepository _orderRepository;
|
||||||
|
|
||||||
|
// Using DI to inject infrastructure persistence Repositories
|
||||||
public CreateOrderCommandHandler(IBuyerRepository buyerRepository, IOrderRepository orderRepository)
|
public CreateOrderCommandHandler(IBuyerRepository buyerRepository, IOrderRepository orderRepository)
|
||||||
{
|
{
|
||||||
if (buyerRepository == null)
|
if (buyerRepository == null)
|
||||||
@ -30,13 +31,16 @@
|
|||||||
|
|
||||||
public async Task<bool> Handle(CreateOrderCommand message)
|
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)
|
if (buyer == null)
|
||||||
{
|
{
|
||||||
buyer = new Buyer(message.BuyerFullName);
|
buyer = new Buyer(message.BuyerIdentityGuid);
|
||||||
}
|
}
|
||||||
|
|
||||||
var payment = buyer.AddPaymentMethod(message.CardTypeId,
|
var payment = buyer.AddPaymentMethod(message.CardTypeId,
|
||||||
@ -51,7 +55,10 @@
|
|||||||
await _buyerRepository.UnitOfWork
|
await _buyerRepository.UnitOfWork
|
||||||
.SaveChangesAsync();
|
.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));
|
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();
|
.SaveChangesAsync();
|
||||||
|
|
||||||
return result > 0;
|
return result > 0;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -13,9 +13,9 @@
|
|||||||
{
|
{
|
||||||
private string _connectionString = string.Empty;
|
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>(
|
var result = await connection.QueryAsync<dynamic>(
|
||||||
@"select o.[Id] as ordernumber,o.OrderDate as date, os.Name as status,
|
@"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,
|
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
|
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.Orderitems oi ON o.Id = oi.orderid
|
||||||
LEFT JOIN ordering.orderstatus os on o.OrderStatusId = os.Id
|
LEFT JOIN ordering.orderstatus os on o.OrderStatusId = os.Id
|
||||||
WHERE o.Id=@id"
|
WHERE o.Id=@id"
|
||||||
|
@ -11,7 +11,7 @@ using System.Threading.Tasks;
|
|||||||
namespace Microsoft.eShopOnContainers.Services.Ordering.API.Controllers
|
namespace Microsoft.eShopOnContainers.Services.Ordering.API.Controllers
|
||||||
{
|
{
|
||||||
[Route("api/v1/[controller]")]
|
[Route("api/v1/[controller]")]
|
||||||
[Authorize]
|
//[Authorize]
|
||||||
public class OrdersController : Controller
|
public class OrdersController : Controller
|
||||||
{
|
{
|
||||||
private readonly IMediator _mediator;
|
private readonly IMediator _mediator;
|
||||||
@ -42,17 +42,17 @@ namespace Microsoft.eShopOnContainers.Services.Ordering.API.Controllers
|
|||||||
|
|
||||||
[Route("new")]
|
[Route("new")]
|
||||||
[HttpPost]
|
[HttpPost]
|
||||||
public async Task<IActionResult> AddOrder([FromBody]CreateOrderCommand createOrderCommand)
|
public async Task<IActionResult> CreateOrder([FromBody]CreateOrderCommand createOrderCommand)
|
||||||
{
|
{
|
||||||
if (createOrderCommand.CardTypeId == 0)
|
if (createOrderCommand.CardTypeId == 0)
|
||||||
{
|
{
|
||||||
createOrderCommand.CardTypeId = 1;
|
createOrderCommand.CardTypeId = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
createOrderCommand.BuyerFullName = _identityService.GetUserIdentity();
|
createOrderCommand.BuyerIdentityGuid = _identityService.GetUserIdentity();
|
||||||
|
|
||||||
var added = await _mediator.SendAsync(createOrderCommand);
|
var result = await _mediator.SendAsync(createOrderCommand);
|
||||||
if (added)
|
if (result)
|
||||||
{
|
{
|
||||||
return Ok();
|
return Ok();
|
||||||
}
|
}
|
||||||
|
@ -10,9 +10,19 @@ namespace Microsoft.eShopOnContainers.Services.Ordering.API.Infrastructure.Autof
|
|||||||
public class ApplicationModule
|
public class ApplicationModule
|
||||||
:Autofac.Module
|
:Autofac.Module
|
||||||
{
|
{
|
||||||
|
|
||||||
|
public string QueriesConnectionString { get; }
|
||||||
|
|
||||||
|
public ApplicationModule(string qconstr)
|
||||||
|
{
|
||||||
|
QueriesConnectionString = qconstr;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
protected override void Load(ContainerBuilder builder)
|
protected override void Load(ContainerBuilder builder)
|
||||||
{
|
{
|
||||||
builder.RegisterType<OrderQueries>()
|
|
||||||
|
builder.Register(c => new OrderQueries(QueriesConnectionString))
|
||||||
.As<IOrderQueries>()
|
.As<IOrderQueries>()
|
||||||
.InstancePerLifetimeScope();
|
.InstancePerLifetimeScope();
|
||||||
|
|
||||||
|
@ -8,7 +8,7 @@ using Microsoft.eShopOnContainers.Services.Ordering.Infrastructure;
|
|||||||
namespace Ordering.API.Migrations
|
namespace Ordering.API.Migrations
|
||||||
{
|
{
|
||||||
[DbContext(typeof(OrderingContext))]
|
[DbContext(typeof(OrderingContext))]
|
||||||
[Migration("20170127103457_Initial")]
|
[Migration("20170208181933_Initial")]
|
||||||
partial class Initial
|
partial class Initial
|
||||||
{
|
{
|
||||||
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||||
@ -29,13 +29,13 @@ namespace Ordering.API.Migrations
|
|||||||
.HasAnnotation("SqlServer:HiLoSequenceSchema", "ordering")
|
.HasAnnotation("SqlServer:HiLoSequenceSchema", "ordering")
|
||||||
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.SequenceHiLo);
|
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.SequenceHiLo);
|
||||||
|
|
||||||
b.Property<string>("FullName")
|
b.Property<string>("IdentityGuid")
|
||||||
.IsRequired()
|
.IsRequired()
|
||||||
.HasMaxLength(200);
|
.HasMaxLength(200);
|
||||||
|
|
||||||
b.HasKey("Id");
|
b.HasKey("Id");
|
||||||
|
|
||||||
b.HasIndex("FullName")
|
b.HasIndex("IdentityGuid")
|
||||||
.IsUnique();
|
.IsUnique();
|
||||||
|
|
||||||
b.ToTable("buyers","ordering");
|
b.ToTable("buyers","ordering");
|
||||||
@ -90,6 +90,26 @@ namespace Ordering.API.Migrations
|
|||||||
b.ToTable("paymentmethods","ordering");
|
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 =>
|
modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate.Order", b =>
|
||||||
{
|
{
|
||||||
b.Property<int>("Id")
|
b.Property<int>("Id")
|
||||||
@ -98,31 +118,20 @@ namespace Ordering.API.Migrations
|
|||||||
.HasAnnotation("SqlServer:HiLoSequenceSchema", "ordering")
|
.HasAnnotation("SqlServer:HiLoSequenceSchema", "ordering")
|
||||||
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.SequenceHiLo);
|
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.SequenceHiLo);
|
||||||
|
|
||||||
|
b.Property<int?>("AddressId");
|
||||||
|
|
||||||
b.Property<int>("BuyerId");
|
b.Property<int>("BuyerId");
|
||||||
|
|
||||||
b.Property<string>("City")
|
|
||||||
.IsRequired();
|
|
||||||
|
|
||||||
b.Property<string>("Country")
|
|
||||||
.IsRequired();
|
|
||||||
|
|
||||||
b.Property<DateTime>("OrderDate");
|
b.Property<DateTime>("OrderDate");
|
||||||
|
|
||||||
b.Property<int>("OrderStatusId");
|
b.Property<int>("OrderStatusId");
|
||||||
|
|
||||||
b.Property<int>("PaymentMethodId");
|
b.Property<int>("PaymentMethodId");
|
||||||
|
|
||||||
b.Property<string>("State")
|
|
||||||
.IsRequired();
|
|
||||||
|
|
||||||
b.Property<string>("Street")
|
|
||||||
.IsRequired();
|
|
||||||
|
|
||||||
b.Property<string>("ZipCode")
|
|
||||||
.IsRequired();
|
|
||||||
|
|
||||||
b.HasKey("Id");
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("AddressId");
|
||||||
|
|
||||||
b.HasIndex("BuyerId");
|
b.HasIndex("BuyerId");
|
||||||
|
|
||||||
b.HasIndex("OrderStatusId");
|
b.HasIndex("OrderStatusId");
|
||||||
@ -190,6 +199,10 @@ namespace Ordering.API.Migrations
|
|||||||
|
|
||||||
modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate.Order", b =>
|
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")
|
b.HasOne("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.BuyerAggregate.Buyer", "Buyer")
|
||||||
.WithMany()
|
.WithMany()
|
||||||
.HasForeignKey("BuyerId")
|
.HasForeignKey("BuyerId")
|
@ -1,6 +1,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using Microsoft.EntityFrameworkCore.Migrations;
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
using Microsoft.EntityFrameworkCore.Metadata;
|
||||||
|
|
||||||
namespace Ordering.API.Migrations
|
namespace Ordering.API.Migrations
|
||||||
{
|
{
|
||||||
@ -36,7 +37,7 @@ namespace Ordering.API.Migrations
|
|||||||
columns: table => new
|
columns: table => new
|
||||||
{
|
{
|
||||||
Id = table.Column<int>(nullable: false),
|
Id = table.Column<int>(nullable: false),
|
||||||
FullName = table.Column<string>(maxLength: 200, nullable: false)
|
IdentityGuid = table.Column<string>(maxLength: 200, nullable: false)
|
||||||
},
|
},
|
||||||
constraints: table =>
|
constraints: table =>
|
||||||
{
|
{
|
||||||
@ -56,6 +57,24 @@ namespace Ordering.API.Migrations
|
|||||||
table.PrimaryKey("PK_cardtypes", x => x.Id);
|
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(
|
migrationBuilder.CreateTable(
|
||||||
name: "orderstatus",
|
name: "orderstatus",
|
||||||
schema: "ordering",
|
schema: "ordering",
|
||||||
@ -107,19 +126,22 @@ namespace Ordering.API.Migrations
|
|||||||
columns: table => new
|
columns: table => new
|
||||||
{
|
{
|
||||||
Id = table.Column<int>(nullable: false),
|
Id = table.Column<int>(nullable: false),
|
||||||
|
AddressId = table.Column<int>(nullable: true),
|
||||||
BuyerId = table.Column<int>(nullable: false),
|
BuyerId = table.Column<int>(nullable: false),
|
||||||
City = table.Column<string>(nullable: false),
|
|
||||||
Country = table.Column<string>(nullable: false),
|
|
||||||
OrderDate = table.Column<DateTime>(nullable: false),
|
OrderDate = table.Column<DateTime>(nullable: false),
|
||||||
OrderStatusId = table.Column<int>(nullable: false),
|
OrderStatusId = table.Column<int>(nullable: false),
|
||||||
PaymentMethodId = 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)
|
|
||||||
},
|
},
|
||||||
constraints: table =>
|
constraints: table =>
|
||||||
{
|
{
|
||||||
table.PrimaryKey("PK_orders", x => x.Id);
|
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(
|
table.ForeignKey(
|
||||||
name: "FK_orders_buyers_BuyerId",
|
name: "FK_orders_buyers_BuyerId",
|
||||||
column: x => x.BuyerId,
|
column: x => x.BuyerId,
|
||||||
@ -170,10 +192,10 @@ namespace Ordering.API.Migrations
|
|||||||
});
|
});
|
||||||
|
|
||||||
migrationBuilder.CreateIndex(
|
migrationBuilder.CreateIndex(
|
||||||
name: "IX_buyers_FullName",
|
name: "IX_buyers_IdentityGuid",
|
||||||
schema: "ordering",
|
schema: "ordering",
|
||||||
table: "buyers",
|
table: "buyers",
|
||||||
column: "FullName",
|
column: "IdentityGuid",
|
||||||
unique: true);
|
unique: true);
|
||||||
|
|
||||||
migrationBuilder.CreateIndex(
|
migrationBuilder.CreateIndex(
|
||||||
@ -188,6 +210,12 @@ namespace Ordering.API.Migrations
|
|||||||
table: "paymentmethods",
|
table: "paymentmethods",
|
||||||
column: "CardTypeId");
|
column: "CardTypeId");
|
||||||
|
|
||||||
|
migrationBuilder.CreateIndex(
|
||||||
|
name: "IX_orders_AddressId",
|
||||||
|
schema: "ordering",
|
||||||
|
table: "orders",
|
||||||
|
column: "AddressId");
|
||||||
|
|
||||||
migrationBuilder.CreateIndex(
|
migrationBuilder.CreateIndex(
|
||||||
name: "IX_orders_BuyerId",
|
name: "IX_orders_BuyerId",
|
||||||
schema: "ordering",
|
schema: "ordering",
|
||||||
@ -223,6 +251,10 @@ namespace Ordering.API.Migrations
|
|||||||
name: "orders",
|
name: "orders",
|
||||||
schema: "ordering");
|
schema: "ordering");
|
||||||
|
|
||||||
|
migrationBuilder.DropTable(
|
||||||
|
name: "address",
|
||||||
|
schema: "ordering");
|
||||||
|
|
||||||
migrationBuilder.DropTable(
|
migrationBuilder.DropTable(
|
||||||
name: "orderstatus",
|
name: "orderstatus",
|
||||||
schema: "ordering");
|
schema: "ordering");
|
@ -28,13 +28,13 @@ namespace Ordering.API.Migrations
|
|||||||
.HasAnnotation("SqlServer:HiLoSequenceSchema", "ordering")
|
.HasAnnotation("SqlServer:HiLoSequenceSchema", "ordering")
|
||||||
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.SequenceHiLo);
|
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.SequenceHiLo);
|
||||||
|
|
||||||
b.Property<string>("FullName")
|
b.Property<string>("IdentityGuid")
|
||||||
.IsRequired()
|
.IsRequired()
|
||||||
.HasMaxLength(200);
|
.HasMaxLength(200);
|
||||||
|
|
||||||
b.HasKey("Id");
|
b.HasKey("Id");
|
||||||
|
|
||||||
b.HasIndex("FullName")
|
b.HasIndex("IdentityGuid")
|
||||||
.IsUnique();
|
.IsUnique();
|
||||||
|
|
||||||
b.ToTable("buyers","ordering");
|
b.ToTable("buyers","ordering");
|
||||||
@ -89,6 +89,26 @@ namespace Ordering.API.Migrations
|
|||||||
b.ToTable("paymentmethods","ordering");
|
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 =>
|
modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate.Order", b =>
|
||||||
{
|
{
|
||||||
b.Property<int>("Id")
|
b.Property<int>("Id")
|
||||||
@ -97,31 +117,20 @@ namespace Ordering.API.Migrations
|
|||||||
.HasAnnotation("SqlServer:HiLoSequenceSchema", "ordering")
|
.HasAnnotation("SqlServer:HiLoSequenceSchema", "ordering")
|
||||||
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.SequenceHiLo);
|
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.SequenceHiLo);
|
||||||
|
|
||||||
|
b.Property<int?>("AddressId");
|
||||||
|
|
||||||
b.Property<int>("BuyerId");
|
b.Property<int>("BuyerId");
|
||||||
|
|
||||||
b.Property<string>("City")
|
|
||||||
.IsRequired();
|
|
||||||
|
|
||||||
b.Property<string>("Country")
|
|
||||||
.IsRequired();
|
|
||||||
|
|
||||||
b.Property<DateTime>("OrderDate");
|
b.Property<DateTime>("OrderDate");
|
||||||
|
|
||||||
b.Property<int>("OrderStatusId");
|
b.Property<int>("OrderStatusId");
|
||||||
|
|
||||||
b.Property<int>("PaymentMethodId");
|
b.Property<int>("PaymentMethodId");
|
||||||
|
|
||||||
b.Property<string>("State")
|
|
||||||
.IsRequired();
|
|
||||||
|
|
||||||
b.Property<string>("Street")
|
|
||||||
.IsRequired();
|
|
||||||
|
|
||||||
b.Property<string>("ZipCode")
|
|
||||||
.IsRequired();
|
|
||||||
|
|
||||||
b.HasKey("Id");
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("AddressId");
|
||||||
|
|
||||||
b.HasIndex("BuyerId");
|
b.HasIndex("BuyerId");
|
||||||
|
|
||||||
b.HasIndex("OrderStatusId");
|
b.HasIndex("OrderStatusId");
|
||||||
@ -189,6 +198,10 @@ namespace Ordering.API.Migrations
|
|||||||
|
|
||||||
modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate.Order", b =>
|
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")
|
b.HasOne("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.BuyerAggregate.Buyer", "Buyer")
|
||||||
.WithMany()
|
.WithMany()
|
||||||
.HasForeignKey("BuyerId")
|
.HasForeignKey("BuyerId")
|
||||||
|
@ -81,7 +81,6 @@
|
|||||||
|
|
||||||
// Add application services.
|
// Add application services.
|
||||||
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
|
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
|
||||||
services.AddSingleton<IConfiguration>(this.Configuration);
|
|
||||||
services.AddTransient<IIdentityService,IdentityService>();
|
services.AddTransient<IIdentityService,IdentityService>();
|
||||||
|
|
||||||
services.AddOptions();
|
services.AddOptions();
|
||||||
@ -92,7 +91,7 @@
|
|||||||
container.Populate(services);
|
container.Populate(services);
|
||||||
|
|
||||||
container.RegisterModule(new MediatorModule());
|
container.RegisterModule(new MediatorModule());
|
||||||
container.RegisterModule(new ApplicationModule());
|
container.RegisterModule(new ApplicationModule(Configuration["ConnectionString"] ));
|
||||||
|
|
||||||
return new AutofacServiceProvider(container.Build());
|
return new AutofacServiceProvider(container.Build());
|
||||||
}
|
}
|
||||||
|
@ -8,11 +8,11 @@ namespace Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.B
|
|||||||
public class Buyer
|
public class Buyer
|
||||||
: Entity, IAggregateRoot
|
: 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() { }
|
protected Buyer() { }
|
||||||
|
|
||||||
@ -23,9 +23,9 @@ namespace Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.B
|
|||||||
throw new ArgumentNullException(nameof(identity));
|
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)
|
public PaymentMethod AddPaymentMethod(int cardTypeId, string alias, string cardNumber, string securityNumber, string cardHolderName, DateTime expiration)
|
||||||
|
@ -7,7 +7,7 @@ namespace Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.B
|
|||||||
//This is just the RepositoryContracts or Interface defined at the Domain Layer
|
//This is just the RepositoryContracts or Interface defined at the Domain Layer
|
||||||
//as requisite for the Buyer Aggregate
|
//as requisite for the Buyer Aggregate
|
||||||
public interface IBuyerRepository
|
public interface IBuyerRepository
|
||||||
:IRepository
|
:IAggregateRepository
|
||||||
{
|
{
|
||||||
Buyer Add(Buyer buyer);
|
Buyer Add(Buyer buyer);
|
||||||
|
|
||||||
|
@ -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
|
namespace Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate
|
||||||
{
|
{
|
||||||
public class Address
|
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)
|
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;
|
Country = country;
|
||||||
ZipCode = zipcode;
|
ZipCode = zipcode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected override IEnumerable<object> GetAtomicValues()
|
||||||
|
{
|
||||||
|
yield return Street;
|
||||||
|
yield return City;
|
||||||
|
yield return State;
|
||||||
|
yield return Country;
|
||||||
|
yield return ZipCode;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,7 @@ namespace Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.O
|
|||||||
//This is just the RepositoryContracts or Interface defined at the Domain Layer
|
//This is just the RepositoryContracts or Interface defined at the Domain Layer
|
||||||
//as requisite for the Order Aggregate
|
//as requisite for the Order Aggregate
|
||||||
public interface IOrderRepository
|
public interface IOrderRepository
|
||||||
:IRepository
|
:IAggregateRepository
|
||||||
{
|
{
|
||||||
Order Add(Order order);
|
Order Add(Order order);
|
||||||
}
|
}
|
||||||
|
@ -9,44 +9,51 @@ namespace Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.O
|
|||||||
public class Order
|
public class Order
|
||||||
: Entity
|
: Entity
|
||||||
{
|
{
|
||||||
private string _street;
|
// DDD Patterns comment
|
||||||
private string _city;
|
// Using private fields, allowed since EF Core 1.1, is a much better encapsulation
|
||||||
private string _state;
|
// aligned with DDD Aggregates and Domain Entities (Instead of properties and property collections)
|
||||||
private string _country;
|
|
||||||
private string _zipCode;
|
|
||||||
private DateTime _orderDate;
|
private DateTime _orderDate;
|
||||||
|
|
||||||
|
public Address Address { get; private set; }
|
||||||
|
|
||||||
public Buyer Buyer { get; private set; }
|
public Buyer Buyer { get; private set; }
|
||||||
int _buyerId;
|
private int _buyerId;
|
||||||
|
|
||||||
public OrderStatus OrderStatus { get; private set; }
|
public OrderStatus OrderStatus { get; private set; }
|
||||||
int _orderStatusId;
|
private int _orderStatusId;
|
||||||
|
|
||||||
HashSet<OrderItem> _orderItems;
|
// DDD Patterns comment
|
||||||
public IEnumerable<OrderItem> OrderItems => _orderItems.ToList().AsEnumerable();
|
// 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;
|
||||||
|
|
||||||
|
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; }
|
public PaymentMethod PaymentMethod { get; private set; }
|
||||||
int _paymentMethodId;
|
private int _paymentMethodId;
|
||||||
|
|
||||||
protected Order() { }
|
protected Order() { }
|
||||||
|
|
||||||
public Order(int buyerId, int paymentMethodId, Address address)
|
public Order(int buyerId, int paymentMethodId, Address address)
|
||||||
{
|
{
|
||||||
|
_orderItems = new List<OrderItem>();
|
||||||
_buyerId = buyerId;
|
_buyerId = buyerId;
|
||||||
_paymentMethodId = paymentMethodId;
|
_paymentMethodId = paymentMethodId;
|
||||||
_orderStatusId = OrderStatus.InProcess.Id;
|
_orderStatusId = OrderStatus.InProcess.Id;
|
||||||
_orderDate = DateTime.UtcNow;
|
_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)
|
public void AddOrderItem(int productId, string productName, decimal unitPrice, decimal discount, string pictureUrl, int units = 1)
|
||||||
{
|
{
|
||||||
var existingOrderForProduct = _orderItems.Where(o => o.ProductId == productId)
|
var existingOrderForProduct = _orderItems.Where(o => o.ProductId == productId)
|
||||||
|
@ -6,16 +6,18 @@ namespace Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.O
|
|||||||
public class OrderItem
|
public class OrderItem
|
||||||
: Entity
|
: Entity
|
||||||
{
|
{
|
||||||
private string _productName;
|
// DDD Patterns comment
|
||||||
private string _pictureUrl;
|
// Using private fields, allowed since EF Core 1.1, is a much better encapsulation
|
||||||
private int _orderId;
|
// 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 _unitPrice;
|
||||||
private decimal _discount;
|
private decimal _discount;
|
||||||
private int _units;
|
private int _units;
|
||||||
|
|
||||||
public int ProductId { get; private set; }
|
public int ProductId { get; private set; }
|
||||||
|
|
||||||
|
|
||||||
protected OrderItem() { }
|
protected OrderItem() { }
|
||||||
|
|
||||||
public OrderItem(int productId, string productName, decimal unitPrice, decimal discount, string PictureUrl, int units = 1)
|
public OrderItem(int productId, string productName, decimal unitPrice, decimal discount, string PictureUrl, int units = 1)
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
namespace Microsoft.eShopOnContainers.Services.Ordering.Domain.Seedwork
|
namespace Microsoft.eShopOnContainers.Services.Ordering.Domain.Seedwork
|
||||||
{
|
{
|
||||||
public interface IRepository
|
public interface IAggregateRepository
|
||||||
{
|
{
|
||||||
IUnitOfWork UnitOfWork { get; }
|
IUnitOfWork UnitOfWork { get; }
|
||||||
}
|
}
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -30,6 +30,7 @@ namespace Microsoft.eShopOnContainers.Services.Ordering.Infrastructure
|
|||||||
|
|
||||||
protected override void OnModelCreating(ModelBuilder modelBuilder)
|
protected override void OnModelCreating(ModelBuilder modelBuilder)
|
||||||
{
|
{
|
||||||
|
modelBuilder.Entity<Address>(ConfigureAddress);
|
||||||
modelBuilder.Entity<Buyer>(ConfigureBuyer);
|
modelBuilder.Entity<Buyer>(ConfigureBuyer);
|
||||||
modelBuilder.Entity<PaymentMethod>(ConfigurePayment);
|
modelBuilder.Entity<PaymentMethod>(ConfigurePayment);
|
||||||
modelBuilder.Entity<Order>(ConfigureOrder);
|
modelBuilder.Entity<Order>(ConfigureOrder);
|
||||||
@ -38,6 +39,16 @@ namespace Microsoft.eShopOnContainers.Services.Ordering.Infrastructure
|
|||||||
modelBuilder.Entity<OrderStatus>(ConfigureOrderStatus);
|
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)
|
void ConfigureBuyer(EntityTypeBuilder<Buyer> buyerConfiguration)
|
||||||
{
|
{
|
||||||
buyerConfiguration.ToTable("buyers", DEFAULT_SCHEMA);
|
buyerConfiguration.ToTable("buyers", DEFAULT_SCHEMA);
|
||||||
@ -47,11 +58,11 @@ namespace Microsoft.eShopOnContainers.Services.Ordering.Infrastructure
|
|||||||
buyerConfiguration.Property(b => b.Id)
|
buyerConfiguration.Property(b => b.Id)
|
||||||
.ForSqlServerUseSequenceHiLo("buyerseq", DEFAULT_SCHEMA);
|
.ForSqlServerUseSequenceHiLo("buyerseq", DEFAULT_SCHEMA);
|
||||||
|
|
||||||
buyerConfiguration.Property(b=>b.FullName)
|
buyerConfiguration.Property(b=>b.IdentityGuid)
|
||||||
.HasMaxLength(200)
|
.HasMaxLength(200)
|
||||||
.IsRequired();
|
.IsRequired();
|
||||||
|
|
||||||
buyerConfiguration.HasIndex("FullName")
|
buyerConfiguration.HasIndex("IdentityGuid")
|
||||||
.IsUnique(true);
|
.IsUnique(true);
|
||||||
|
|
||||||
buyerConfiguration.HasMany(b => b.PaymentMethods)
|
buyerConfiguration.HasMany(b => b.PaymentMethods)
|
||||||
@ -109,17 +120,13 @@ namespace Microsoft.eShopOnContainers.Services.Ordering.Infrastructure
|
|||||||
.ForSqlServerUseSequenceHiLo("orderseq", DEFAULT_SCHEMA);
|
.ForSqlServerUseSequenceHiLo("orderseq", DEFAULT_SCHEMA);
|
||||||
|
|
||||||
orderConfiguration.Property<DateTime>("OrderDate").IsRequired();
|
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>("BuyerId").IsRequired();
|
||||||
orderConfiguration.Property<int>("OrderStatusId").IsRequired();
|
orderConfiguration.Property<int>("OrderStatusId").IsRequired();
|
||||||
orderConfiguration.Property<int>("PaymentMethodId").IsRequired();
|
orderConfiguration.Property<int>("PaymentMethodId").IsRequired();
|
||||||
|
|
||||||
var navigation = orderConfiguration.Metadata.FindNavigation(nameof(Order.OrderItems));
|
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);
|
navigation.SetPropertyAccessMode(PropertyAccessMode.Field);
|
||||||
|
|
||||||
orderConfiguration.HasOne(o => o.PaymentMethod)
|
orderConfiguration.HasOne(o => o.PaymentMethod)
|
||||||
|
@ -49,7 +49,7 @@ namespace Microsoft.eShopOnContainers.Services.Ordering.Infrastructure.Repositor
|
|||||||
{
|
{
|
||||||
var buyer = await _context.Buyers
|
var buyer = await _context.Buyers
|
||||||
.Include(b => b.PaymentMethods)
|
.Include(b => b.PaymentMethods)
|
||||||
.Where(b => b.FullName == identity)
|
.Where(b => b.IdentityGuid == identity)
|
||||||
.SingleOrDefaultAsync();
|
.SingleOrDefaultAsync();
|
||||||
|
|
||||||
return buyer;
|
return buyer;
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
FROM microsoft/aspnetcore:1.0.1
|
FROM microsoft/aspnetcore:1.1
|
||||||
ENTRYPOINT ["dotnet", "WebMVC.dll"]
|
ENTRYPOINT ["dotnet", "WebMVC.dll"]
|
||||||
ARG source=.
|
ARG source=.
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
|
@ -14,12 +14,12 @@ namespace Microsoft.eShopOnContainers.WebMVC.Services
|
|||||||
{
|
{
|
||||||
public class BasketService : IBasketService
|
public class BasketService : IBasketService
|
||||||
{
|
{
|
||||||
private readonly IOptions<AppSettings> _settings;
|
private readonly IOptionsSnapshot<AppSettings> _settings;
|
||||||
private HttpClient _apiClient;
|
private HttpClient _apiClient;
|
||||||
private readonly string _remoteServiceBaseUrl;
|
private readonly string _remoteServiceBaseUrl;
|
||||||
private IHttpContextAccessor _httpContextAccesor;
|
private IHttpContextAccessor _httpContextAccesor;
|
||||||
|
|
||||||
public BasketService(IOptions<AppSettings> settings, IHttpContextAccessor httpContextAccesor)
|
public BasketService(IOptionsSnapshot<AppSettings> settings, IHttpContextAccessor httpContextAccesor)
|
||||||
{
|
{
|
||||||
_settings = settings;
|
_settings = settings;
|
||||||
_remoteServiceBaseUrl = _settings.Value.BasketUrl;
|
_remoteServiceBaseUrl = _settings.Value.BasketUrl;
|
||||||
|
@ -15,11 +15,11 @@ namespace Microsoft.eShopOnContainers.WebMVC.Services
|
|||||||
{
|
{
|
||||||
public class CatalogService : ICatalogService
|
public class CatalogService : ICatalogService
|
||||||
{
|
{
|
||||||
private readonly IOptions<AppSettings> _settings;
|
private readonly IOptionsSnapshot<AppSettings> _settings;
|
||||||
private HttpClient _apiClient;
|
private HttpClient _apiClient;
|
||||||
private readonly string _remoteServiceBaseUrl;
|
private readonly string _remoteServiceBaseUrl;
|
||||||
|
|
||||||
public CatalogService(IOptions<AppSettings> settings, ILoggerFactory loggerFactory) {
|
public CatalogService(IOptionsSnapshot<AppSettings> settings, ILoggerFactory loggerFactory) {
|
||||||
_settings = settings;
|
_settings = settings;
|
||||||
_remoteServiceBaseUrl = $"{_settings.Value.CatalogUrl}/api/v1/catalog/";
|
_remoteServiceBaseUrl = $"{_settings.Value.CatalogUrl}/api/v1/catalog/";
|
||||||
|
|
||||||
|
@ -15,10 +15,10 @@ namespace Microsoft.eShopOnContainers.WebMVC.Services
|
|||||||
{
|
{
|
||||||
private HttpClient _apiClient;
|
private HttpClient _apiClient;
|
||||||
private readonly string _remoteServiceBaseUrl;
|
private readonly string _remoteServiceBaseUrl;
|
||||||
private readonly IOptions<AppSettings> _settings;
|
private readonly IOptionsSnapshot<AppSettings> _settings;
|
||||||
private readonly IHttpContextAccessor _httpContextAccesor;
|
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";
|
_remoteServiceBaseUrl = $"{settings.Value.OrderingUrl}/api/v1/orders";
|
||||||
_settings = settings;
|
_settings = settings;
|
||||||
|
@ -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-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.Total)</section>
|
||||||
<section class="esh-orders-item col-xs-2">@Html.DisplayFor(modelItem => item.Status)</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>
|
<a class="esh-orders-link" asp-controller="Order" asp-action="Detail" asp-route-orderId="@item.OrderNumber">Detail</a>
|
||||||
</section>
|
</section>
|
||||||
</article>
|
</article>
|
||||||
|
@ -2,27 +2,27 @@
|
|||||||
"userSecretsId": "aspnet-Microsoft.eShopOnContainers-946ae052-8305-4a99-965b-ec8636ddbae3",
|
"userSecretsId": "aspnet-Microsoft.eShopOnContainers-946ae052-8305-4a99-965b-ec8636ddbae3",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"Microsoft.NETCore.App": {
|
"Microsoft.NETCore.App": {
|
||||||
"version": "1.0.0",
|
"version": "1.1.0",
|
||||||
"type": "platform"
|
"type": "platform"
|
||||||
},
|
},
|
||||||
"Microsoft.AspNetCore.Authentication.Cookies": "1.0.0",
|
"Microsoft.AspNetCore.Authentication.Cookies": "1.1.0",
|
||||||
"Microsoft.AspNetCore.Diagnostics": "1.0.0",
|
"Microsoft.AspNetCore.Diagnostics": "1.1.0",
|
||||||
"Microsoft.AspNetCore.Mvc": "1.0.0",
|
"Microsoft.AspNetCore.Mvc": "1.1.1",
|
||||||
"Microsoft.AspNetCore.Razor.Tools": {
|
"Microsoft.AspNetCore.Razor.Tools": {
|
||||||
"version": "1.0.0-preview2-final",
|
"version": "1.0.0-preview2-final",
|
||||||
"type": "build"
|
"type": "build"
|
||||||
},
|
},
|
||||||
"Microsoft.AspNetCore.Server.IISIntegration": "1.0.0",
|
"Microsoft.AspNetCore.Server.IISIntegration": "1.1.0",
|
||||||
"Microsoft.AspNetCore.Server.Kestrel": "1.0.0",
|
"Microsoft.AspNetCore.Server.Kestrel": "1.1.0",
|
||||||
"Microsoft.AspNetCore.StaticFiles": "1.0.0",
|
"Microsoft.AspNetCore.StaticFiles": "1.1.0",
|
||||||
"Microsoft.Extensions.Configuration.EnvironmentVariables": "1.0.0",
|
"Microsoft.Extensions.Configuration.EnvironmentVariables": "1.1.0",
|
||||||
"Microsoft.Extensions.Configuration.Json": "1.0.0",
|
"Microsoft.Extensions.Configuration.Json": "1.1.0",
|
||||||
"Microsoft.Extensions.Configuration.UserSecrets": "1.0.0",
|
"Microsoft.Extensions.Configuration.UserSecrets": "1.1.0",
|
||||||
"Microsoft.Extensions.Logging": "1.0.0",
|
"Microsoft.Extensions.Logging": "1.1.0",
|
||||||
"Microsoft.Extensions.Logging.Console": "1.0.0",
|
"Microsoft.Extensions.Logging.Console": "1.1.0",
|
||||||
"Microsoft.Extensions.Logging.Debug": "1.0.0",
|
"Microsoft.Extensions.Logging.Debug": "1.1.0",
|
||||||
"Microsoft.Extensions.Options.ConfigurationExtensions": "1.0.0",
|
"Microsoft.Extensions.Options.ConfigurationExtensions": "1.1.0",
|
||||||
"Microsoft.VisualStudio.Web.BrowserLink.Loader": "14.0.0",
|
"Microsoft.VisualStudio.Web.BrowserLink.Loader": "14.1.0",
|
||||||
"Microsoft.VisualStudio.Web.CodeGeneration.Tools": {
|
"Microsoft.VisualStudio.Web.CodeGeneration.Tools": {
|
||||||
"version": "1.0.0-preview2-final",
|
"version": "1.0.0-preview2-final",
|
||||||
"type": "build"
|
"type": "build"
|
||||||
@ -32,10 +32,11 @@
|
|||||||
"type": "build"
|
"type": "build"
|
||||||
},
|
},
|
||||||
"Newtonsoft.Json": "9.0.1",
|
"Newtonsoft.Json": "9.0.1",
|
||||||
"System.IdentityModel.Tokens.Jwt": "5.0.0",
|
"System.IdentityModel.Tokens.Jwt": "5.1.0",
|
||||||
"Microsoft.AspNetCore.Authentication.OpenIdConnect": "1.0.0",
|
"Microsoft.AspNetCore.Authentication.OpenIdConnect": "1.1.0",
|
||||||
"Microsoft.AspNetCore.Authentication.JwtBearer": "1.0.0",
|
"Microsoft.AspNetCore.Authentication.JwtBearer": "1.1.0",
|
||||||
"Microsoft.AspNetCore.Identity.EntityFrameworkCore": "1.0.0"
|
"Microsoft.AspNetCore.Identity.EntityFrameworkCore": "1.1.0",
|
||||||
|
"Microsoft.Extensions.Options": "1.1.0"
|
||||||
},
|
},
|
||||||
"tools": {
|
"tools": {
|
||||||
"BundlerMinifier.Core": "2.0.238",
|
"BundlerMinifier.Core": "2.0.238",
|
||||||
|
@ -16,7 +16,7 @@
|
|||||||
<section class="esh-orders-item col-xs-4">{{order.date | date:'short'}}</section>
|
<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.total}}</section>
|
||||||
<section class="esh-orders-item col-xs-2">{{order.status}}</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>
|
<a class="esh-orders-link" routerLink="/orders/{{order.ordernumber}}">Detail</a>
|
||||||
</section>
|
</section>
|
||||||
</article>
|
</article>
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
FROM microsoft/aspnetcore:1.0.1
|
FROM microsoft/aspnetcore:1.1
|
||||||
ENTRYPOINT ["dotnet", "eShopOnContainers.WebSPA.dll"]
|
ENTRYPOINT ["dotnet", "eShopOnContainers.WebSPA.dll"]
|
||||||
ARG source=.
|
ARG source=.
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
|
@ -11,9 +11,9 @@ namespace eShopConContainers.WebSPA.Server.Controllers
|
|||||||
public class HomeController : Controller
|
public class HomeController : Controller
|
||||||
{
|
{
|
||||||
private readonly IHostingEnvironment _env;
|
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;
|
_env = env;
|
||||||
_settings = settings;
|
_settings = settings;
|
||||||
|
@ -2,16 +2,16 @@
|
|||||||
"userSecretsId": "aspnetcorespa-c23d27a4-eb88-4b18-9b77-2a93f3b15119",
|
"userSecretsId": "aspnetcorespa-c23d27a4-eb88-4b18-9b77-2a93f3b15119",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"Microsoft.NETCore.App": {
|
"Microsoft.NETCore.App": {
|
||||||
"version": "1.0.0",
|
"version": "1.1.0",
|
||||||
"type": "platform"
|
"type": "platform"
|
||||||
},
|
},
|
||||||
"Microsoft.Extensions.Configuration.UserSecrets": "1.0.0",
|
"Microsoft.Extensions.Configuration.UserSecrets": "1.1.0",
|
||||||
"Microsoft.AspNetCore.Authentication.Cookies": "1.0.0",
|
"Microsoft.AspNetCore.Authentication.Cookies": "1.1.0",
|
||||||
"Microsoft.AspNetCore.Diagnostics": "1.0.0",
|
"Microsoft.AspNetCore.Diagnostics": "1.1.0",
|
||||||
"Microsoft.AspNetCore.Mvc": "1.0.1",
|
"Microsoft.AspNetCore.Mvc": "1.1.1",
|
||||||
"Microsoft.AspNetCore.Cors": "1.0.0",
|
"Microsoft.AspNetCore.Cors": "1.1.0",
|
||||||
"Microsoft.AspNetCore.Antiforgery": "1.0.1",
|
"Microsoft.AspNetCore.Antiforgery": "1.1.0",
|
||||||
"Microsoft.AspNetCore.Authorization": "1.0.0",
|
"Microsoft.AspNetCore.Authorization": "1.1.0",
|
||||||
"Newtonsoft.Json": "9.0.1",
|
"Newtonsoft.Json": "9.0.1",
|
||||||
"Webpack": "3.0.0",
|
"Webpack": "3.0.0",
|
||||||
"Microsoft.AspNetCore.AngularServices": "1.0.0-beta-000014",
|
"Microsoft.AspNetCore.AngularServices": "1.0.0-beta-000014",
|
||||||
@ -19,15 +19,15 @@
|
|||||||
"version": "1.0.0-preview2-final",
|
"version": "1.0.0-preview2-final",
|
||||||
"type": "build"
|
"type": "build"
|
||||||
},
|
},
|
||||||
"Microsoft.AspNetCore.Server.IISIntegration": "1.0.0",
|
"Microsoft.AspNetCore.Server.IISIntegration": "1.1.0",
|
||||||
"Microsoft.AspNetCore.Server.Kestrel": "1.0.0",
|
"Microsoft.AspNetCore.Server.Kestrel": "1.1.0",
|
||||||
"Microsoft.AspNetCore.StaticFiles": "1.0.0",
|
"Microsoft.AspNetCore.StaticFiles": "1.1.0",
|
||||||
"Microsoft.Extensions.Configuration.EnvironmentVariables": "1.0.0",
|
"Microsoft.Extensions.Configuration.EnvironmentVariables": "1.1.0",
|
||||||
"Microsoft.Extensions.Configuration.Json": "1.0.0",
|
"Microsoft.Extensions.Configuration.Json": "1.1.0",
|
||||||
"Microsoft.Extensions.Logging": "1.0.0",
|
"Microsoft.Extensions.Logging": "1.1.0",
|
||||||
"Microsoft.Extensions.Logging.Console": "1.0.0",
|
"Microsoft.Extensions.Logging.Console": "1.1.0",
|
||||||
"Microsoft.Extensions.Logging.Debug": "1.0.0",
|
"Microsoft.Extensions.Logging.Debug": "1.1.0",
|
||||||
"Microsoft.Extensions.Options.ConfigurationExtensions": "1.0.0",
|
"Microsoft.Extensions.Options.ConfigurationExtensions": "1.1.0",
|
||||||
"Microsoft.VisualStudio.Web.CodeGeneration.Tools": {
|
"Microsoft.VisualStudio.Web.CodeGeneration.Tools": {
|
||||||
"version": "1.0.0-preview2-final",
|
"version": "1.0.0-preview2-final",
|
||||||
"type": "build"
|
"type": "build"
|
||||||
@ -36,7 +36,8 @@
|
|||||||
"version": "1.0.0-preview2-final",
|
"version": "1.0.0-preview2-final",
|
||||||
"type": "build"
|
"type": "build"
|
||||||
},
|
},
|
||||||
"Microsoft.AspNetCore.Http.Abstractions": "1.0.0"
|
"Microsoft.AspNetCore.Http.Abstractions": "1.1.0",
|
||||||
|
"Microsoft.Extensions.Options": "1.1.0"
|
||||||
},
|
},
|
||||||
"tools": {
|
"tools": {
|
||||||
"Microsoft.DotNet.Watcher.Tools": {
|
"Microsoft.DotNet.Watcher.Tools": {
|
||||||
|
@ -25,7 +25,7 @@ namespace UnitTest.Ordering.Application
|
|||||||
public async Task Handle_returns_true_when_order_is_persisted_succesfully()
|
public async Task Handle_returns_true_when_order_is_persisted_succesfully()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
_buyerRepositoryMock.Setup(buyerRepo => buyerRepo.FindAsync(FakeOrderRequestWithBuyer().BuyerFullName))
|
_buyerRepositoryMock.Setup(buyerRepo => buyerRepo.FindAsync(FakeOrderRequestWithBuyer().BuyerIdentityGuid))
|
||||||
.Returns(Task.FromResult<Buyer>(FakeBuyer()));
|
.Returns(Task.FromResult<Buyer>(FakeBuyer()));
|
||||||
|
|
||||||
_buyerRepositoryMock.Setup(buyerRepo => buyerRepo.UnitOfWork.SaveChangesAsync(default(CancellationToken)))
|
_buyerRepositoryMock.Setup(buyerRepo => buyerRepo.UnitOfWork.SaveChangesAsync(default(CancellationToken)))
|
||||||
@ -48,7 +48,7 @@ namespace UnitTest.Ordering.Application
|
|||||||
[Fact]
|
[Fact]
|
||||||
public async Task Handle_return_false_if_order_is_not_persisted()
|
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()));
|
.Returns(Task.FromResult<Buyer>(FakeBuyer()));
|
||||||
|
|
||||||
_buyerRepositoryMock.Setup(buyerRepo => buyerRepo.UnitOfWork.SaveChangesAsync(default(CancellationToken)))
|
_buyerRepositoryMock.Setup(buyerRepo => buyerRepo.UnitOfWork.SaveChangesAsync(default(CancellationToken)))
|
||||||
@ -80,7 +80,7 @@ namespace UnitTest.Ordering.Application
|
|||||||
{
|
{
|
||||||
return new CreateOrderCommand
|
return new CreateOrderCommand
|
||||||
{
|
{
|
||||||
BuyerFullName = "1234",
|
BuyerIdentityGuid = "1234",
|
||||||
CardNumber = "1234",
|
CardNumber = "1234",
|
||||||
CardExpiration = DateTime.Now.AddYears(1),
|
CardExpiration = DateTime.Now.AddYears(1),
|
||||||
CardSecurityNumber = "123",
|
CardSecurityNumber = "123",
|
||||||
|
Loading…
x
Reference in New Issue
Block a user