Browse Source

Refactored namespaces for ordering.infrastructure project

pull/1770/head
Sumit Ghosh 3 years ago
parent
commit
c007047291
13 changed files with 439 additions and 527 deletions
  1. +21
    -27
      src/Services/Ordering/Ordering.Infrastructure/EntityConfigurations/BuyerEntityTypeConfiguration.cs
  2. +13
    -19
      src/Services/Ordering/Ordering.Infrastructure/EntityConfigurations/CardTypeEntityTypeConfiguration.cs
  3. +8
    -14
      src/Services/Ordering/Ordering.Infrastructure/EntityConfigurations/ClientRequestEntityTypeConfiguration.cs
  4. +59
    -67
      src/Services/Ordering/Ordering.Infrastructure/EntityConfigurations/OrderEntityTypeConfiguration.cs
  5. +48
    -54
      src/Services/Ordering/Ordering.Infrastructure/EntityConfigurations/OrderItemEntityTypeConfiguration.cs
  6. +13
    -19
      src/Services/Ordering/Ordering.Infrastructure/EntityConfigurations/OrderStatusEntityTypeConfiguration.cs
  7. +53
    -60
      src/Services/Ordering/Ordering.Infrastructure/EntityConfigurations/PaymentMethodEntityTypeConfiguration.cs
  8. +5
    -8
      src/Services/Ordering/Ordering.Infrastructure/Idempotency/ClientRequest.cs
  9. +4
    -8
      src/Services/Ordering/Ordering.Infrastructure/Idempotency/IRequestManager.cs
  10. +26
    -31
      src/Services/Ordering/Ordering.Infrastructure/Idempotency/RequestManager.cs
  11. +105
    -120
      src/Services/Ordering/Ordering.Infrastructure/OrderingContext.cs
  12. +43
    -51
      src/Services/Ordering/Ordering.Infrastructure/Repositories/BuyerRepository.cs
  13. +41
    -49
      src/Services/Ordering/Ordering.Infrastructure/Repositories/OrderRepository.cs

+ 21
- 27
src/Services/Ordering/Ordering.Infrastructure/EntityConfigurations/BuyerEntityTypeConfiguration.cs View File

@ -1,41 +1,35 @@
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
using Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.BuyerAggregate;
using Microsoft.eShopOnContainers.Services.Ordering.Infrastructure;
namespace Microsoft.eShopOnContainers.Services.Ordering.Infrastructure.EntityConfigurations;
namespace Ordering.Infrastructure.EntityConfigurations
class BuyerEntityTypeConfiguration
: IEntityTypeConfiguration<Buyer>
{
class BuyerEntityTypeConfiguration
: IEntityTypeConfiguration<Buyer>
public void Configure(EntityTypeBuilder<Buyer> buyerConfiguration)
{
public void Configure(EntityTypeBuilder<Buyer> buyerConfiguration)
{
buyerConfiguration.ToTable("buyers", OrderingContext.DEFAULT_SCHEMA);
buyerConfiguration.ToTable("buyers", OrderingContext.DEFAULT_SCHEMA);
buyerConfiguration.HasKey(b => b.Id);
buyerConfiguration.HasKey(b => b.Id);
buyerConfiguration.Ignore(b => b.DomainEvents);
buyerConfiguration.Ignore(b => b.DomainEvents);
buyerConfiguration.Property(b => b.Id)
.UseHiLo("buyerseq", OrderingContext.DEFAULT_SCHEMA);
buyerConfiguration.Property(b => b.Id)
.UseHiLo("buyerseq", OrderingContext.DEFAULT_SCHEMA);
buyerConfiguration.Property(b => b.IdentityGuid)
.HasMaxLength(200)
.IsRequired();
buyerConfiguration.Property(b => b.IdentityGuid)
.HasMaxLength(200)
.IsRequired();
buyerConfiguration.HasIndex("IdentityGuid")
.IsUnique(true);
buyerConfiguration.HasIndex("IdentityGuid")
.IsUnique(true);
buyerConfiguration.Property(b => b.Name);
buyerConfiguration.Property(b => b.Name);
buyerConfiguration.HasMany(b => b.PaymentMethods)
.WithOne()
.HasForeignKey("BuyerId")
.OnDelete(DeleteBehavior.Cascade);
buyerConfiguration.HasMany(b => b.PaymentMethods)
.WithOne()
.HasForeignKey("BuyerId")
.OnDelete(DeleteBehavior.Cascade);
var navigation = buyerConfiguration.Metadata.FindNavigation(nameof(Buyer.PaymentMethods));
var navigation = buyerConfiguration.Metadata.FindNavigation(nameof(Buyer.PaymentMethods));
navigation.SetPropertyAccessMode(PropertyAccessMode.Field);
}
navigation.SetPropertyAccessMode(PropertyAccessMode.Field);
}
}

+ 13
- 19
src/Services/Ordering/Ordering.Infrastructure/EntityConfigurations/CardTypeEntityTypeConfiguration.cs View File

@ -1,27 +1,21 @@
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
using Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.BuyerAggregate;
using Microsoft.eShopOnContainers.Services.Ordering.Infrastructure;
namespace Microsoft.eShopOnContainers.Services.Ordering.Infrastructure.EntityConfigurations;
namespace Ordering.Infrastructure.EntityConfigurations
class CardTypeEntityTypeConfiguration
: IEntityTypeConfiguration<CardType>
{
class CardTypeEntityTypeConfiguration
: IEntityTypeConfiguration<CardType>
public void Configure(EntityTypeBuilder<CardType> cardTypesConfiguration)
{
public void Configure(EntityTypeBuilder<CardType> cardTypesConfiguration)
{
cardTypesConfiguration.ToTable("cardtypes", OrderingContext.DEFAULT_SCHEMA);
cardTypesConfiguration.ToTable("cardtypes", OrderingContext.DEFAULT_SCHEMA);
cardTypesConfiguration.HasKey(ct => ct.Id);
cardTypesConfiguration.HasKey(ct => ct.Id);
cardTypesConfiguration.Property(ct => ct.Id)
.HasDefaultValue(1)
.ValueGeneratedNever()
.IsRequired();
cardTypesConfiguration.Property(ct => ct.Id)
.HasDefaultValue(1)
.ValueGeneratedNever()
.IsRequired();
cardTypesConfiguration.Property(ct => ct.Name)
.HasMaxLength(200)
.IsRequired();
}
cardTypesConfiguration.Property(ct => ct.Name)
.HasMaxLength(200)
.IsRequired();
}
}

+ 8
- 14
src/Services/Ordering/Ordering.Infrastructure/EntityConfigurations/ClientRequestEntityTypeConfiguration.cs View File

@ -1,19 +1,13 @@
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
using Microsoft.eShopOnContainers.Services.Ordering.Infrastructure;
using Microsoft.eShopOnContainers.Services.Ordering.Infrastructure.Idempotency;
namespace Microsoft.eShopOnContainers.Services.Ordering.Infrastructure.EntityConfigurations;
namespace Ordering.Infrastructure.EntityConfigurations
class ClientRequestEntityTypeConfiguration
: IEntityTypeConfiguration<ClientRequest>
{
class ClientRequestEntityTypeConfiguration
: IEntityTypeConfiguration<ClientRequest>
public void Configure(EntityTypeBuilder<ClientRequest> requestConfiguration)
{
public void Configure(EntityTypeBuilder<ClientRequest> requestConfiguration)
{
requestConfiguration.ToTable("requests", OrderingContext.DEFAULT_SCHEMA);
requestConfiguration.HasKey(cr => cr.Id);
requestConfiguration.Property(cr => cr.Name).IsRequired();
requestConfiguration.Property(cr => cr.Time).IsRequired();
}
requestConfiguration.ToTable("requests", OrderingContext.DEFAULT_SCHEMA);
requestConfiguration.HasKey(cr => cr.Id);
requestConfiguration.Property(cr => cr.Name).IsRequired();
requestConfiguration.Property(cr => cr.Time).IsRequired();
}
}

+ 59
- 67
src/Services/Ordering/Ordering.Infrastructure/EntityConfigurations/OrderEntityTypeConfiguration.cs View File

@ -1,86 +1,78 @@
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
using Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.BuyerAggregate;
using Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate;
using Microsoft.eShopOnContainers.Services.Ordering.Infrastructure;
using System;
namespace Microsoft.eShopOnContainers.Services.Ordering.Infrastructure.EntityConfigurations;
namespace Ordering.Infrastructure.EntityConfigurations
class OrderEntityTypeConfiguration : IEntityTypeConfiguration<Order>
{
class OrderEntityTypeConfiguration : IEntityTypeConfiguration<Order>
public void Configure(EntityTypeBuilder<Order> orderConfiguration)
{
public void Configure(EntityTypeBuilder<Order> orderConfiguration)
{
orderConfiguration.ToTable("orders", OrderingContext.DEFAULT_SCHEMA);
orderConfiguration.ToTable("orders", OrderingContext.DEFAULT_SCHEMA);
orderConfiguration.HasKey(o => o.Id);
orderConfiguration.HasKey(o => o.Id);
orderConfiguration.Ignore(b => b.DomainEvents);
orderConfiguration.Ignore(b => b.DomainEvents);
orderConfiguration.Property(o => o.Id)
.UseHiLo("orderseq", OrderingContext.DEFAULT_SCHEMA);
orderConfiguration.Property(o => o.Id)
.UseHiLo("orderseq", OrderingContext.DEFAULT_SCHEMA);
//Address value object persisted as owned entity type supported since EF Core 2.0
orderConfiguration
.OwnsOne(o => o.Address, a =>
{
// Explicit configuration of the shadow key property in the owned type
// as a workaround for a documented issue in EF Core 5: https://github.com/dotnet/efcore/issues/20740
a.Property<int>("OrderId")
.UseHiLo("orderseq", OrderingContext.DEFAULT_SCHEMA);
a.WithOwner();
});
//Address value object persisted as owned entity type supported since EF Core 2.0
orderConfiguration
.OwnsOne(o => o.Address, a =>
{
// Explicit configuration of the shadow key property in the owned type
// as a workaround for a documented issue in EF Core 5: https://github.com/dotnet/efcore/issues/20740
a.Property<int>("OrderId")
.UseHiLo("orderseq", OrderingContext.DEFAULT_SCHEMA);
a.WithOwner();
});
orderConfiguration
.Property<int?>("_buyerId")
.UsePropertyAccessMode(PropertyAccessMode.Field)
.HasColumnName("BuyerId")
.IsRequired(false);
orderConfiguration
.Property<int?>("_buyerId")
.UsePropertyAccessMode(PropertyAccessMode.Field)
.HasColumnName("BuyerId")
.IsRequired(false);
orderConfiguration
.Property<DateTime>("_orderDate")
.UsePropertyAccessMode(PropertyAccessMode.Field)
.HasColumnName("OrderDate")
.IsRequired();
orderConfiguration
.Property<DateTime>("_orderDate")
.UsePropertyAccessMode(PropertyAccessMode.Field)
.HasColumnName("OrderDate")
.IsRequired();
orderConfiguration
.Property<int>("_orderStatusId")
// .HasField("_orderStatusId")
.UsePropertyAccessMode(PropertyAccessMode.Field)
.HasColumnName("OrderStatusId")
.IsRequired();
orderConfiguration
.Property<int>("_orderStatusId")
// .HasField("_orderStatusId")
.UsePropertyAccessMode(PropertyAccessMode.Field)
.HasColumnName("OrderStatusId")
.IsRequired();
orderConfiguration
.Property<int?>("_paymentMethodId")
.UsePropertyAccessMode(PropertyAccessMode.Field)
.HasColumnName("PaymentMethodId")
.IsRequired(false);
orderConfiguration
.Property<int?>("_paymentMethodId")
.UsePropertyAccessMode(PropertyAccessMode.Field)
.HasColumnName("PaymentMethodId")
.IsRequired(false);
orderConfiguration.Property<string>("Description").IsRequired(false);
orderConfiguration.Property<string>("Description").IsRequired(false);
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);
// DDD Patterns comment:
//Set as field (New since EF 1.1) to access the OrderItem collection property through its field
navigation.SetPropertyAccessMode(PropertyAccessMode.Field);
orderConfiguration.HasOne<PaymentMethod>()
.WithMany()
// .HasForeignKey("PaymentMethodId")
.HasForeignKey("_paymentMethodId")
.IsRequired(false)
.OnDelete(DeleteBehavior.Restrict);
orderConfiguration.HasOne<PaymentMethod>()
.WithMany()
// .HasForeignKey("PaymentMethodId")
.HasForeignKey("_paymentMethodId")
.IsRequired(false)
.OnDelete(DeleteBehavior.Restrict);
orderConfiguration.HasOne<Buyer>()
.WithMany()
.IsRequired(false)
// .HasForeignKey("BuyerId");
.HasForeignKey("_buyerId");
orderConfiguration.HasOne<Buyer>()
.WithMany()
.IsRequired(false)
// .HasForeignKey("BuyerId");
.HasForeignKey("_buyerId");
orderConfiguration.HasOne(o => o.OrderStatus)
.WithMany()
// .HasForeignKey("OrderStatusId");
.HasForeignKey("_orderStatusId");
}
orderConfiguration.HasOne(o => o.OrderStatus)
.WithMany()
// .HasForeignKey("OrderStatusId");
.HasForeignKey("_orderStatusId");
}
}

+ 48
- 54
src/Services/Ordering/Ordering.Infrastructure/EntityConfigurations/OrderItemEntityTypeConfiguration.cs View File

@ -1,59 +1,53 @@
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
using Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate;
using Microsoft.eShopOnContainers.Services.Ordering.Infrastructure;
namespace Microsoft.eShopOnContainers.Services.Ordering.Infrastructure.EntityConfigurations;
namespace Ordering.Infrastructure.EntityConfigurations
class OrderItemEntityTypeConfiguration
: IEntityTypeConfiguration<OrderItem>
{
class OrderItemEntityTypeConfiguration
: IEntityTypeConfiguration<OrderItem>
public void Configure(EntityTypeBuilder<OrderItem> orderItemConfiguration)
{
public void Configure(EntityTypeBuilder<OrderItem> orderItemConfiguration)
{
orderItemConfiguration.ToTable("orderItems", OrderingContext.DEFAULT_SCHEMA);
orderItemConfiguration.HasKey(o => o.Id);
orderItemConfiguration.Ignore(b => b.DomainEvents);
orderItemConfiguration.Property(o => o.Id)
.UseHiLo("orderitemseq");
orderItemConfiguration.Property<int>("OrderId")
.IsRequired();
orderItemConfiguration
.Property<decimal>("_discount")
.UsePropertyAccessMode(PropertyAccessMode.Field)
.HasColumnName("Discount")
.IsRequired();
orderItemConfiguration.Property<int>("ProductId")
.IsRequired();
orderItemConfiguration
.Property<string>("_productName")
.UsePropertyAccessMode(PropertyAccessMode.Field)
.HasColumnName("ProductName")
.IsRequired();
orderItemConfiguration
.Property<decimal>("_unitPrice")
.UsePropertyAccessMode(PropertyAccessMode.Field)
.HasColumnName("UnitPrice")
.IsRequired();
orderItemConfiguration
.Property<int>("_units")
.UsePropertyAccessMode(PropertyAccessMode.Field)
.HasColumnName("Units")
.IsRequired();
orderItemConfiguration
.Property<string>("_pictureUrl")
.UsePropertyAccessMode(PropertyAccessMode.Field)
.HasColumnName("PictureUrl")
.IsRequired(false);
}
orderItemConfiguration.ToTable("orderItems", OrderingContext.DEFAULT_SCHEMA);
orderItemConfiguration.HasKey(o => o.Id);
orderItemConfiguration.Ignore(b => b.DomainEvents);
orderItemConfiguration.Property(o => o.Id)
.UseHiLo("orderitemseq");
orderItemConfiguration.Property<int>("OrderId")
.IsRequired();
orderItemConfiguration
.Property<decimal>("_discount")
.UsePropertyAccessMode(PropertyAccessMode.Field)
.HasColumnName("Discount")
.IsRequired();
orderItemConfiguration.Property<int>("ProductId")
.IsRequired();
orderItemConfiguration
.Property<string>("_productName")
.UsePropertyAccessMode(PropertyAccessMode.Field)
.HasColumnName("ProductName")
.IsRequired();
orderItemConfiguration
.Property<decimal>("_unitPrice")
.UsePropertyAccessMode(PropertyAccessMode.Field)
.HasColumnName("UnitPrice")
.IsRequired();
orderItemConfiguration
.Property<int>("_units")
.UsePropertyAccessMode(PropertyAccessMode.Field)
.HasColumnName("Units")
.IsRequired();
orderItemConfiguration
.Property<string>("_pictureUrl")
.UsePropertyAccessMode(PropertyAccessMode.Field)
.HasColumnName("PictureUrl")
.IsRequired(false);
}
}

+ 13
- 19
src/Services/Ordering/Ordering.Infrastructure/EntityConfigurations/OrderStatusEntityTypeConfiguration.cs View File

@ -1,27 +1,21 @@
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
using Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate;
using Microsoft.eShopOnContainers.Services.Ordering.Infrastructure;
namespace Microsoft.eShopOnContainers.Services.Ordering.Infrastructure.EntityConfigurations;
namespace Ordering.Infrastructure.EntityConfigurations
class OrderStatusEntityTypeConfiguration
: IEntityTypeConfiguration<OrderStatus>
{
class OrderStatusEntityTypeConfiguration
: IEntityTypeConfiguration<OrderStatus>
public void Configure(EntityTypeBuilder<OrderStatus> orderStatusConfiguration)
{
public void Configure(EntityTypeBuilder<OrderStatus> orderStatusConfiguration)
{
orderStatusConfiguration.ToTable("orderstatus", OrderingContext.DEFAULT_SCHEMA);
orderStatusConfiguration.ToTable("orderstatus", OrderingContext.DEFAULT_SCHEMA);
orderStatusConfiguration.HasKey(o => o.Id);
orderStatusConfiguration.HasKey(o => o.Id);
orderStatusConfiguration.Property(o => o.Id)
.HasDefaultValue(1)
.ValueGeneratedNever()
.IsRequired();
orderStatusConfiguration.Property(o => o.Id)
.HasDefaultValue(1)
.ValueGeneratedNever()
.IsRequired();
orderStatusConfiguration.Property(o => o.Name)
.HasMaxLength(200)
.IsRequired();
}
orderStatusConfiguration.Property(o => o.Name)
.HasMaxLength(200)
.IsRequired();
}
}

+ 53
- 60
src/Services/Ordering/Ordering.Infrastructure/EntityConfigurations/PaymentMethodEntityTypeConfiguration.cs View File

@ -1,65 +1,58 @@
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
using Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.BuyerAggregate;
using Microsoft.eShopOnContainers.Services.Ordering.Infrastructure;
using System;
namespace Microsoft.eShopOnContainers.Services.Ordering.Infrastructure.EntityConfigurations;
namespace Ordering.Infrastructure.EntityConfigurations
class PaymentMethodEntityTypeConfiguration
: IEntityTypeConfiguration<PaymentMethod>
{
class PaymentMethodEntityTypeConfiguration
: IEntityTypeConfiguration<PaymentMethod>
public void Configure(EntityTypeBuilder<PaymentMethod> paymentConfiguration)
{
public void Configure(EntityTypeBuilder<PaymentMethod> paymentConfiguration)
{
paymentConfiguration.ToTable("paymentmethods", OrderingContext.DEFAULT_SCHEMA);
paymentConfiguration.HasKey(b => b.Id);
paymentConfiguration.Ignore(b => b.DomainEvents);
paymentConfiguration.Property(b => b.Id)
.UseHiLo("paymentseq", OrderingContext.DEFAULT_SCHEMA);
paymentConfiguration.Property<int>("BuyerId")
.IsRequired();
paymentConfiguration
.Property<string>("_cardHolderName")
.UsePropertyAccessMode(PropertyAccessMode.Field)
.HasColumnName("CardHolderName")
.HasMaxLength(200)
.IsRequired();
paymentConfiguration
.Property<string>("_alias")
.UsePropertyAccessMode(PropertyAccessMode.Field)
.HasColumnName("Alias")
.HasMaxLength(200)
.IsRequired();
paymentConfiguration
.Property<string>("_cardNumber")
.UsePropertyAccessMode(PropertyAccessMode.Field)
.HasColumnName("CardNumber")
.HasMaxLength(25)
.IsRequired();
paymentConfiguration
.Property<DateTime>("_expiration")
.UsePropertyAccessMode(PropertyAccessMode.Field)
.HasColumnName("Expiration")
.HasMaxLength(25)
.IsRequired();
paymentConfiguration
.Property<int>("_cardTypeId")
.UsePropertyAccessMode(PropertyAccessMode.Field)
.HasColumnName("CardTypeId")
.IsRequired();
paymentConfiguration.HasOne(p => p.CardType)
.WithMany()
.HasForeignKey("_cardTypeId");
}
paymentConfiguration.ToTable("paymentmethods", OrderingContext.DEFAULT_SCHEMA);
paymentConfiguration.HasKey(b => b.Id);
paymentConfiguration.Ignore(b => b.DomainEvents);
paymentConfiguration.Property(b => b.Id)
.UseHiLo("paymentseq", OrderingContext.DEFAULT_SCHEMA);
paymentConfiguration.Property<int>("BuyerId")
.IsRequired();
paymentConfiguration
.Property<string>("_cardHolderName")
.UsePropertyAccessMode(PropertyAccessMode.Field)
.HasColumnName("CardHolderName")
.HasMaxLength(200)
.IsRequired();
paymentConfiguration
.Property<string>("_alias")
.UsePropertyAccessMode(PropertyAccessMode.Field)
.HasColumnName("Alias")
.HasMaxLength(200)
.IsRequired();
paymentConfiguration
.Property<string>("_cardNumber")
.UsePropertyAccessMode(PropertyAccessMode.Field)
.HasColumnName("CardNumber")
.HasMaxLength(25)
.IsRequired();
paymentConfiguration
.Property<DateTime>("_expiration")
.UsePropertyAccessMode(PropertyAccessMode.Field)
.HasColumnName("Expiration")
.HasMaxLength(25)
.IsRequired();
paymentConfiguration
.Property<int>("_cardTypeId")
.UsePropertyAccessMode(PropertyAccessMode.Field)
.HasColumnName("CardTypeId")
.IsRequired();
paymentConfiguration.HasOne(p => p.CardType)
.WithMany()
.HasForeignKey("_cardTypeId");
}
}

+ 5
- 8
src/Services/Ordering/Ordering.Infrastructure/Idempotency/ClientRequest.cs View File

@ -1,11 +1,8 @@
using System;
namespace Microsoft.eShopOnContainers.Services.Ordering.Infrastructure.Idempotency;
namespace Microsoft.eShopOnContainers.Services.Ordering.Infrastructure.Idempotency
public class ClientRequest
{
public class ClientRequest
{
public Guid Id { get; set; }
public string Name { get; set; }
public DateTime Time { get; set; }
}
public Guid Id { get; set; }
public string Name { get; set; }
public DateTime Time { get; set; }
}

+ 4
- 8
src/Services/Ordering/Ordering.Infrastructure/Idempotency/IRequestManager.cs View File

@ -1,12 +1,8 @@
using System;
using System.Threading.Tasks;
namespace Microsoft.eShopOnContainers.Services.Ordering.Infrastructure.Idempotency;
namespace Microsoft.eShopOnContainers.Services.Ordering.Infrastructure.Idempotency
public interface IRequestManager
{
public interface IRequestManager
{
Task<bool> ExistAsync(Guid id);
Task<bool> ExistAsync(Guid id);
Task CreateRequestForCommandAsync<T>(Guid id);
}
Task CreateRequestForCommandAsync<T>(Guid id);
}

+ 26
- 31
src/Services/Ordering/Ordering.Infrastructure/Idempotency/RequestManager.cs View File

@ -1,43 +1,38 @@
using Ordering.Domain.Exceptions;
using System;
using System.Threading.Tasks;
namespace Microsoft.eShopOnContainers.Services.Ordering.Infrastructure.Idempotency;
namespace Microsoft.eShopOnContainers.Services.Ordering.Infrastructure.Idempotency
public class RequestManager : IRequestManager
{
public class RequestManager : IRequestManager
{
private readonly OrderingContext _context;
private readonly OrderingContext _context;
public RequestManager(OrderingContext context)
{
_context = context ?? throw new ArgumentNullException(nameof(context));
}
public RequestManager(OrderingContext context)
{
_context = context ?? throw new ArgumentNullException(nameof(context));
}
public async Task<bool> ExistAsync(Guid id)
{
var request = await _context.
FindAsync<ClientRequest>(id);
public async Task<bool> ExistAsync(Guid id)
{
var request = await _context.
FindAsync<ClientRequest>(id);
return request != null;
}
return request != null;
}
public async Task CreateRequestForCommandAsync<T>(Guid id)
{
var exists = await ExistAsync(id);
public async Task CreateRequestForCommandAsync<T>(Guid id)
{
var exists = await ExistAsync(id);
var request = exists ?
throw new OrderingDomainException($"Request with {id} already exists") :
new ClientRequest()
{
Id = id,
Name = typeof(T).Name,
Time = DateTime.UtcNow
};
var request = exists ?
throw new OrderingDomainException($"Request with {id} already exists") :
new ClientRequest()
{
Id = id,
Name = typeof(T).Name,
Time = DateTime.UtcNow
};
_context.Add(request);
_context.Add(request);
await _context.SaveChangesAsync();
}
await _context.SaveChangesAsync();
}
}

+ 105
- 120
src/Services/Ordering/Ordering.Infrastructure/OrderingContext.cs View File

@ -1,156 +1,141 @@
using MediatR;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Design;
using Microsoft.EntityFrameworkCore.Storage;
using Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.BuyerAggregate;
using Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate;
using Microsoft.eShopOnContainers.Services.Ordering.Domain.Seedwork;
using Ordering.Infrastructure;
using Ordering.Infrastructure.EntityConfigurations;
using System;
using System.Data;
using System.Threading;
using System.Threading.Tasks;
namespace Microsoft.eShopOnContainers.Services.Ordering.Infrastructure
namespace Microsoft.eShopOnContainers.Services.Ordering.Infrastructure;
public class OrderingContext : DbContext, IUnitOfWork
{
public class OrderingContext : DbContext, IUnitOfWork
public const string DEFAULT_SCHEMA = "ordering";
public DbSet<Order> Orders { get; set; }
public DbSet<OrderItem> OrderItems { get; set; }
public DbSet<PaymentMethod> Payments { get; set; }
public DbSet<Buyer> Buyers { get; set; }
public DbSet<CardType> CardTypes { get; set; }
public DbSet<OrderStatus> OrderStatus { get; set; }
private readonly IMediator _mediator;
private IDbContextTransaction _currentTransaction;
public OrderingContext(DbContextOptions<OrderingContext> options) : base(options) { }
public IDbContextTransaction GetCurrentTransaction() => _currentTransaction;
public bool HasActiveTransaction => _currentTransaction != null;
public OrderingContext(DbContextOptions<OrderingContext> options, IMediator mediator) : base(options)
{
public const string DEFAULT_SCHEMA = "ordering";
public DbSet<Order> Orders { get; set; }
public DbSet<OrderItem> OrderItems { get; set; }
public DbSet<PaymentMethod> Payments { get; set; }
public DbSet<Buyer> Buyers { get; set; }
public DbSet<CardType> CardTypes { get; set; }
public DbSet<OrderStatus> OrderStatus { get; set; }
_mediator = mediator ?? throw new ArgumentNullException(nameof(mediator));
private readonly IMediator _mediator;
private IDbContextTransaction _currentTransaction;
public OrderingContext(DbContextOptions<OrderingContext> options) : base(options) { }
System.Diagnostics.Debug.WriteLine("OrderingContext::ctor ->" + this.GetHashCode());
}
public IDbContextTransaction GetCurrentTransaction() => _currentTransaction;
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.ApplyConfiguration(new ClientRequestEntityTypeConfiguration());
modelBuilder.ApplyConfiguration(new PaymentMethodEntityTypeConfiguration());
modelBuilder.ApplyConfiguration(new OrderEntityTypeConfiguration());
modelBuilder.ApplyConfiguration(new OrderItemEntityTypeConfiguration());
modelBuilder.ApplyConfiguration(new CardTypeEntityTypeConfiguration());
modelBuilder.ApplyConfiguration(new OrderStatusEntityTypeConfiguration());
modelBuilder.ApplyConfiguration(new BuyerEntityTypeConfiguration());
}
public bool HasActiveTransaction => _currentTransaction != null;
public async Task<bool> SaveEntitiesAsync(CancellationToken cancellationToken = default(CancellationToken))
{
// Dispatch Domain Events collection.
// Choices:
// A) Right BEFORE committing data (EF SaveChanges) into the DB will make a single transaction including
// side effects from the domain event handlers which are using the same DbContext with "InstancePerLifetimeScope" or "scoped" lifetime
// B) Right AFTER committing data (EF SaveChanges) into the DB will make multiple transactions.
// You will need to handle eventual consistency and compensatory actions in case of failures in any of the Handlers.
await _mediator.DispatchDomainEventsAsync(this);
// After executing this line all the changes (from the Command Handler and Domain Event Handlers)
// performed through the DbContext will be committed
var result = await base.SaveChangesAsync(cancellationToken);
return true;
}
public OrderingContext(DbContextOptions<OrderingContext> options, IMediator mediator) : base(options)
{
_mediator = mediator ?? throw new ArgumentNullException(nameof(mediator));
public async Task<IDbContextTransaction> BeginTransactionAsync()
{
if (_currentTransaction != null) return null;
_currentTransaction = await Database.BeginTransactionAsync(IsolationLevel.ReadCommitted);
System.Diagnostics.Debug.WriteLine("OrderingContext::ctor ->" + this.GetHashCode());
}
return _currentTransaction;
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.ApplyConfiguration(new ClientRequestEntityTypeConfiguration());
modelBuilder.ApplyConfiguration(new PaymentMethodEntityTypeConfiguration());
modelBuilder.ApplyConfiguration(new OrderEntityTypeConfiguration());
modelBuilder.ApplyConfiguration(new OrderItemEntityTypeConfiguration());
modelBuilder.ApplyConfiguration(new CardTypeEntityTypeConfiguration());
modelBuilder.ApplyConfiguration(new OrderStatusEntityTypeConfiguration());
modelBuilder.ApplyConfiguration(new BuyerEntityTypeConfiguration());
}
public async Task CommitTransactionAsync(IDbContextTransaction transaction)
{
if (transaction == null) throw new ArgumentNullException(nameof(transaction));
if (transaction != _currentTransaction) throw new InvalidOperationException($"Transaction {transaction.TransactionId} is not current");
public async Task<bool> SaveEntitiesAsync(CancellationToken cancellationToken = default(CancellationToken))
try
{
// Dispatch Domain Events collection.
// Choices:
// A) Right BEFORE committing data (EF SaveChanges) into the DB will make a single transaction including
// side effects from the domain event handlers which are using the same DbContext with "InstancePerLifetimeScope" or "scoped" lifetime
// B) Right AFTER committing data (EF SaveChanges) into the DB will make multiple transactions.
// You will need to handle eventual consistency and compensatory actions in case of failures in any of the Handlers.
await _mediator.DispatchDomainEventsAsync(this);
// After executing this line all the changes (from the Command Handler and Domain Event Handlers)
// performed through the DbContext will be committed
var result = await base.SaveChangesAsync(cancellationToken);
return true;
await SaveChangesAsync();
transaction.Commit();
}
public async Task<IDbContextTransaction> BeginTransactionAsync()
catch
{
if (_currentTransaction != null) return null;
_currentTransaction = await Database.BeginTransactionAsync(IsolationLevel.ReadCommitted);
return _currentTransaction;
RollbackTransaction();
throw;
}
public async Task CommitTransactionAsync(IDbContextTransaction transaction)
finally
{
if (transaction == null) throw new ArgumentNullException(nameof(transaction));
if (transaction != _currentTransaction) throw new InvalidOperationException($"Transaction {transaction.TransactionId} is not current");
try
{
await SaveChangesAsync();
transaction.Commit();
}
catch
{
RollbackTransaction();
throw;
}
finally
if (_currentTransaction != null)
{
if (_currentTransaction != null)
{
_currentTransaction.Dispose();
_currentTransaction = null;
}
_currentTransaction.Dispose();
_currentTransaction = null;
}
}
}
public void RollbackTransaction()
public void RollbackTransaction()
{
try
{
try
{
_currentTransaction?.Rollback();
}
finally
_currentTransaction?.Rollback();
}
finally
{
if (_currentTransaction != null)
{
if (_currentTransaction != null)
{
_currentTransaction.Dispose();
_currentTransaction = null;
}
_currentTransaction.Dispose();
_currentTransaction = null;
}
}
}
}
public class OrderingContextDesignFactory : IDesignTimeDbContextFactory<OrderingContext>
public class OrderingContextDesignFactory : IDesignTimeDbContextFactory<OrderingContext>
{
public OrderingContext CreateDbContext(string[] args)
{
public OrderingContext CreateDbContext(string[] args)
{
var optionsBuilder = new DbContextOptionsBuilder<OrderingContext>()
.UseSqlServer("Server=.;Initial Catalog=Microsoft.eShopOnContainers.Services.OrderingDb;Integrated Security=true");
var optionsBuilder = new DbContextOptionsBuilder<OrderingContext>()
.UseSqlServer("Server=.;Initial Catalog=Microsoft.eShopOnContainers.Services.OrderingDb;Integrated Security=true");
return new OrderingContext(optionsBuilder.Options, new NoMediator());
}
return new OrderingContext(optionsBuilder.Options, new NoMediator());
}
class NoMediator : IMediator
class NoMediator : IMediator
{
public Task Publish<TNotification>(TNotification notification, CancellationToken cancellationToken = default(CancellationToken)) where TNotification : INotification
{
public Task Publish<TNotification>(TNotification notification, CancellationToken cancellationToken = default(CancellationToken)) where TNotification : INotification
{
return Task.CompletedTask;
}
return Task.CompletedTask;
}
public Task Publish(object notification, CancellationToken cancellationToken = default)
{
return Task.CompletedTask;
}
public Task Publish(object notification, CancellationToken cancellationToken = default)
{
return Task.CompletedTask;
}
public Task<TResponse> Send<TResponse>(IRequest<TResponse> request, CancellationToken cancellationToken = default(CancellationToken))
{
return Task.FromResult<TResponse>(default(TResponse));
}
public Task<TResponse> Send<TResponse>(IRequest<TResponse> request, CancellationToken cancellationToken = default(CancellationToken))
{
return Task.FromResult<TResponse>(default(TResponse));
}
public Task<object> Send(object request, CancellationToken cancellationToken = default)
{
return Task.FromResult(default(object));
}
public Task<object> Send(object request, CancellationToken cancellationToken = default)
{
return Task.FromResult(default(object));
}
}
}

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

@ -1,68 +1,60 @@
using Microsoft.EntityFrameworkCore;
using Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.BuyerAggregate;
using Microsoft.eShopOnContainers.Services.Ordering.Domain.Seedwork;
using System;
using System.Linq;
using System.Threading.Tasks;
namespace Microsoft.eShopOnContainers.Services.Ordering.Infrastructure.Repositories;
namespace Microsoft.eShopOnContainers.Services.Ordering.Infrastructure.Repositories
public class BuyerRepository
: IBuyerRepository
{
public class BuyerRepository
: IBuyerRepository
private readonly OrderingContext _context;
public IUnitOfWork UnitOfWork
{
private readonly OrderingContext _context;
public IUnitOfWork UnitOfWork
get
{
get
{
return _context;
}
}
public BuyerRepository(OrderingContext context)
{
_context = context ?? throw new ArgumentNullException(nameof(context));
return _context;
}
}
public Buyer Add(Buyer buyer)
{
if (buyer.IsTransient())
{
return _context.Buyers
.Add(buyer)
.Entity;
}
else
{
return buyer;
}
}
public BuyerRepository(OrderingContext context)
{
_context = context ?? throw new ArgumentNullException(nameof(context));
}
public Buyer Update(Buyer buyer)
public Buyer Add(Buyer buyer)
{
if (buyer.IsTransient())
{
return _context.Buyers
.Update(buyer)
.Entity;
.Add(buyer)
.Entity;
}
public async Task<Buyer> FindAsync(string identity)
else
{
var buyer = await _context.Buyers
.Include(b => b.PaymentMethods)
.Where(b => b.IdentityGuid == identity)
.SingleOrDefaultAsync();
return buyer;
}
}
public async Task<Buyer> FindByIdAsync(string id)
{
var buyer = await _context.Buyers
.Include(b => b.PaymentMethods)
.Where(b => b.Id == int.Parse(id))
.SingleOrDefaultAsync();
public Buyer Update(Buyer buyer)
{
return _context.Buyers
.Update(buyer)
.Entity;
}
return buyer;
}
public async Task<Buyer> FindAsync(string identity)
{
var buyer = await _context.Buyers
.Include(b => b.PaymentMethods)
.Where(b => b.IdentityGuid == identity)
.SingleOrDefaultAsync();
return buyer;
}
public async Task<Buyer> FindByIdAsync(string id)
{
var buyer = await _context.Buyers
.Include(b => b.PaymentMethods)
.Where(b => b.Id == int.Parse(id))
.SingleOrDefaultAsync();
return buyer;
}
}

+ 41
- 49
src/Services/Ordering/Ordering.Infrastructure/Repositories/OrderRepository.cs View File

@ -1,63 +1,55 @@
using Microsoft.EntityFrameworkCore;
using Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate;
using Microsoft.eShopOnContainers.Services.Ordering.Domain.Seedwork;
using System;
using System.Linq;
using System.Threading.Tasks;
namespace Microsoft.eShopOnContainers.Services.Ordering.Infrastructure.Repositories
namespace Microsoft.eShopOnContainers.Services.Ordering.Infrastructure.Repositories;
public class OrderRepository
: IOrderRepository
{
public class OrderRepository
: IOrderRepository
{
private readonly OrderingContext _context;
private readonly OrderingContext _context;
public IUnitOfWork UnitOfWork
public IUnitOfWork UnitOfWork
{
get
{
get
{
return _context;
}
return _context;
}
}
public OrderRepository(OrderingContext context)
{
_context = context ?? throw new ArgumentNullException(nameof(context));
}
public OrderRepository(OrderingContext context)
{
_context = context ?? throw new ArgumentNullException(nameof(context));
}
public Order Add(Order order)
{
return _context.Orders.Add(order).Entity;
public Order Add(Order order)
{
return _context.Orders.Add(order).Entity;
}
}
public async Task<Order> GetAsync(int orderId)
{
var order = await _context
.Orders
.Include(x => x.Address)
.FirstOrDefaultAsync(o => o.Id == orderId);
if (order == null)
{
order = _context
public async Task<Order> GetAsync(int orderId)
{
var order = await _context
.Orders
.Local
.FirstOrDefault(o => o.Id == orderId);
}
if (order != null)
{
await _context.Entry(order)
.Collection(i => i.OrderItems).LoadAsync();
await _context.Entry(order)
.Reference(i => i.OrderStatus).LoadAsync();
}
return order;
.Include(x => x.Address)
.FirstOrDefaultAsync(o => o.Id == orderId);
if (order == null)
{
order = _context
.Orders
.Local
.FirstOrDefault(o => o.Id == orderId);
}
public void Update(Order order)
if (order != null)
{
_context.Entry(order).State = EntityState.Modified;
await _context.Entry(order)
.Collection(i => i.OrderItems).LoadAsync();
await _context.Entry(order)
.Reference(i => i.OrderStatus).LoadAsync();
}
return order;
}
public void Update(Order order)
{
_context.Entry(order).State = EntityState.Modified;
}
}

Loading…
Cancel
Save