订单微服务实体实现

This commit is contained in:
hello 2024-08-29 23:07:14 +08:00
parent b0b9491dfe
commit 2201f36422
69 changed files with 1042 additions and 67 deletions

View File

@ -1,7 +1,7 @@
// Copyright (c) HelloShop Corporation. All rights reserved.
// See the license file in the project root for more information.
namespace HelloShop.IdentityService;
namespace HelloShop.IdentityService.Authentication;
public class CustomJwtBearerDefaults
{

View File

@ -5,7 +5,7 @@ using HelloShop.IdentityService.Entities;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Identity;
namespace HelloShop.IdentityService;
namespace HelloShop.IdentityService.Authentication;
public static class CustomJwtBearerExtensions
{

View File

@ -10,7 +10,7 @@ using System.Security.Claims;
using System.Text;
using System.Text.Encodings.Web;
namespace HelloShop.IdentityService;
namespace HelloShop.IdentityService.Authentication;
public class CustomJwtBearerHandler(IOptionsMonitor<CustomJwtBearerOptions> options, ILoggerFactory logger, UrlEncoder encoder) : SignInAuthenticationHandler<CustomJwtBearerOptions>(options, logger, encoder)
{

View File

@ -4,7 +4,7 @@
using Microsoft.AspNetCore.Authentication;
using Microsoft.IdentityModel.Tokens;
namespace HelloShop.IdentityService;
namespace HelloShop.IdentityService.Authentication;
public class CustomJwtBearerOptions : AuthenticationSchemeOptions
{

View File

@ -6,7 +6,7 @@ using Microsoft.AspNetCore.Identity;
using Microsoft.Extensions.Options;
using System.Security.Claims;
namespace HelloShop.IdentityService;
namespace HelloShop.IdentityService.Authentication;
public class CustomUserClaimsPrincipalFactory<TUser, TRole>(UserManager<TUser> userManager, RoleManager<TRole> roleManager, IOptions<IdentityOptions> options) : UserClaimsPrincipalFactory<TUser, TRole>(userManager, roleManager, options) where TUser : IdentityUser<int> where TRole : IdentityRole<int>
{

View File

@ -2,7 +2,7 @@
// See the license file in the project root for more information.
using HelloShop.IdentityService.Entities;
using HelloShop.IdentityService.EntityFrameworks;
using HelloShop.IdentityService.Infrastructure;
using HelloShop.ServiceDefaults.Authorization;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Caching.Distributed;

View File

@ -1,7 +1,9 @@
// Copyright (c) HelloShop Corporation. All rights reserved.
// See the license file in the project root for more information.
using HelloShop.IdentityService.Authentication;
using HelloShop.IdentityService.Entities;
using HelloShop.IdentityService.Models.Accounts;
using Microsoft.AspNetCore.Authentication.BearerToken;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Http.HttpResults;
@ -13,7 +15,7 @@ using System.Diagnostics;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
namespace HelloShop.IdentityService;
namespace HelloShop.IdentityService.Controllers;
[Route("api/[controller]")]
[ApiController]

View File

@ -2,7 +2,7 @@
// See the license file in the project root for more information.
using HelloShop.IdentityService.Entities;
using HelloShop.IdentityService.EntityFrameworks;
using HelloShop.IdentityService.Infrastructure;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;

View File

@ -4,8 +4,9 @@
using AutoMapper;
using FluentValidation;
using HelloShop.IdentityService.Entities;
using HelloShop.IdentityService.EntityFrameworks;
using HelloShop.IdentityService.Infrastructure;
using HelloShop.IdentityService.Models.Users;
using HelloShop.IdentityService.PermissionProviders;
using HelloShop.ServiceDefaults.Authorization;
using HelloShop.ServiceDefaults.Extensions;
using HelloShop.ServiceDefaults.Models.Paging;

View File

@ -10,9 +10,9 @@ namespace HelloShop.IdentityService.DataSeeding
{
public class UserDataSeedingProvider(UserManager<User> userManager, RoleManager<Role> roleManager) : IDataSeedingProvider
{
public async Task SeedingAsync(IServiceProvider ServiceProvider)
public async Task SeedingAsync(IServiceProvider ServiceProvider, CancellationToken cancellationToken = default)
{
var adminRole = await roleManager.Roles.SingleOrDefaultAsync(x => x.Name == "AdminRole");
var adminRole = await roleManager.Roles.SingleOrDefaultAsync(x => x.Name == "AdminRole", cancellationToken);
if (adminRole == null)
{
@ -20,7 +20,7 @@ namespace HelloShop.IdentityService.DataSeeding
await roleManager.CreateAsync(adminRole);
}
var guestRole = await roleManager.Roles.SingleOrDefaultAsync(x => x.Name == "GuestRole");
var guestRole = await roleManager.Roles.SingleOrDefaultAsync(x => x.Name == "GuestRole", cancellationToken: cancellationToken);
if (guestRole == null)
{

View File

@ -4,7 +4,7 @@
using HelloShop.IdentityService.Entities;
using Microsoft.EntityFrameworkCore;
namespace HelloShop.IdentityService.EntityFrameworks.EntityConfigurations;
namespace HelloShop.IdentityService.Infrastructure.EntityConfigurations;
public class PermissionGrantedEntityTypeConfiguration : IEntityTypeConfiguration<PermissionGranted>
{

View File

@ -5,7 +5,7 @@ using Microsoft.AspNetCore.Identity;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
namespace HelloShop.IdentityService.EntityFrameworks.EntityConfigurations
namespace HelloShop.IdentityService.Infrastructure.EntityConfigurations
{
public class RoleClaimEntityTypeConfiguration : IEntityTypeConfiguration<IdentityRoleClaim<int>>
{

View File

@ -5,7 +5,7 @@ using HelloShop.IdentityService.Entities;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
namespace HelloShop.IdentityService.EntityFrameworks.EntityConfigurations
namespace HelloShop.IdentityService.Infrastructure.EntityConfigurations
{
public class RoleEntityTypeConfiguration : IEntityTypeConfiguration<Role>
{

View File

@ -5,7 +5,7 @@ using Microsoft.AspNetCore.Identity;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
namespace HelloShop.IdentityService.EntityFrameworks.EntityConfigurations
namespace HelloShop.IdentityService.Infrastructure.EntityConfigurations
{
public class UserClaimEntityTypeConfiguration : IEntityTypeConfiguration<IdentityUserClaim<int>>
{

View File

@ -5,7 +5,7 @@ using HelloShop.IdentityService.Entities;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
namespace HelloShop.IdentityService.EntityFrameworks.EntityConfigurations
namespace HelloShop.IdentityService.Infrastructure.EntityConfigurations
{
public class UserEntityTypeConfiguration : IEntityTypeConfiguration<User>
{

View File

@ -5,7 +5,7 @@ using Microsoft.AspNetCore.Identity;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
namespace HelloShop.IdentityService.EntityFrameworks.EntityConfigurations
namespace HelloShop.IdentityService.Infrastructure.EntityConfigurations
{
public class UserLoginEntityTypeConfiguration : IEntityTypeConfiguration<IdentityUserLogin<int>>
{

View File

@ -4,7 +4,7 @@
using Microsoft.AspNetCore.Identity;
using Microsoft.EntityFrameworkCore;
namespace HelloShop.IdentityService.EntityFrameworks.EntityConfigurations
namespace HelloShop.IdentityService.Infrastructure.EntityConfigurations
{
public class UserRoleEntityTypeConfiguration : IEntityTypeConfiguration<IdentityUserRole<int>>
{

View File

@ -5,7 +5,7 @@ using Microsoft.AspNetCore.Identity;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
namespace HelloShop.IdentityService.EntityFrameworks.EntityConfigurations
namespace HelloShop.IdentityService.Infrastructure.EntityConfigurations
{
public class UserTokenEntityTypeConfiguration : IEntityTypeConfiguration<IdentityUserToken<int>>
{

View File

@ -6,7 +6,7 @@ using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore;
using System.Reflection;
namespace HelloShop.IdentityService.EntityFrameworks
namespace HelloShop.IdentityService.Infrastructure
{
public class IdentityServiceDbContext(DbContextOptions<IdentityServiceDbContext> options) : IdentityDbContext<User, Role, int>(options)
{

View File

@ -1,6 +1,6 @@
// <auto-generated />
using System;
using HelloShop.IdentityService.EntityFrameworks;
using HelloShop.IdentityService.Infrastructure;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;

View File

@ -1,6 +1,6 @@
// <auto-generated />
using System;
using HelloShop.IdentityService.EntityFrameworks;
using HelloShop.IdentityService.Infrastructure;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;

View File

@ -1,6 +1,6 @@
```shell
dotnet ef database drop --force
dotnet ef migrations remove
dotnet ef migrations add InitialCreate --output-dir EntityFrameworks/Migrations
dotnet ef migrations add InitialCreate --output-dir Infrastructure/Migrations
dotnet ef database update
```

View File

@ -3,7 +3,7 @@
using System.Text.Json.Serialization;
namespace HelloShop.IdentityService;
namespace HelloShop.IdentityService.Models.Accounts;
public class AccountLoginRequest
{

View File

@ -1,7 +1,7 @@
// Copyright (c) HelloShop Corporation. All rights reserved.
// See the license file in the project root for more information.
namespace HelloShop.IdentityService;
namespace HelloShop.IdentityService.Models.Accounts;
public class AccountRefreshRequest
{

View File

@ -1,7 +1,7 @@
// Copyright (c) HelloShop Corporation. All rights reserved.
// See the license file in the project root for more information.
namespace HelloShop.IdentityService;
namespace HelloShop.IdentityService.Models.Accounts;
public class AccountRegisterRequest
{

View File

@ -1,7 +1,7 @@
// Copyright (c) HelloShop Corporation. All rights reserved.
// See the license file in the project root for more information.
namespace HelloShop.IdentityService;
namespace HelloShop.IdentityService.Models.Users;
public class UserListItem
{

View File

@ -3,7 +3,7 @@
using HelloShop.ServiceDefaults.Permissions;
namespace HelloShop.IdentityService;
namespace HelloShop.IdentityService.PermissionProviders;
public class IdentityPermissionDefinitionProvider : IPermissionDefinitionProvider
{

View File

@ -1,7 +1,7 @@
// Copyright (c) HelloShop Corporation. All rights reserved.
// See the license file in the project root for more information.
namespace HelloShop.IdentityService;
namespace HelloShop.IdentityService.PermissionProviders;
public static class IdentityPermissions
{

View File

@ -1,11 +1,11 @@
// Copyright (c) HelloShop Corporation. All rights reserved.
// See the license file in the project root for more information.
using HelloShop.IdentityService;
using HelloShop.IdentityService.Authentication;
using HelloShop.IdentityService.Authorization;
using HelloShop.IdentityService.Constants;
using HelloShop.IdentityService.Entities;
using HelloShop.IdentityService.EntityFrameworks;
using HelloShop.IdentityService.Infrastructure;
using HelloShop.ServiceDefaults.Authorization;
using HelloShop.ServiceDefaults.Extensions;
using Microsoft.AspNetCore.Authentication.JwtBearer;

View File

@ -3,7 +3,7 @@
using FluentValidation;
using HelloShop.IdentityService.Entities;
using HelloShop.IdentityService.EntityFrameworks;
using HelloShop.IdentityService.Infrastructure;
using HelloShop.IdentityService.Models.Users;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Localization;

View File

@ -3,7 +3,7 @@
using FluentValidation;
using HelloShop.IdentityService.Entities;
using HelloShop.IdentityService.EntityFrameworks;
using HelloShop.IdentityService.Infrastructure;
using HelloShop.IdentityService.Models.Users;
using Microsoft.EntityFrameworkCore;

View File

@ -0,0 +1,12 @@
// Copyright (c) HelloShop Corporation. All rights reserved.
// See the license file in the project root for more information.
namespace HelloShop.OrderingService.Constants
{
public class DbConstants
{
public const string MasterConnectionStringName = "OrderingDatabaseMaster";
public const string SlaveConnectionStringName = "OrderingDatabaseSlave";
}
}

View File

@ -0,0 +1,16 @@
// Copyright (c) HelloShop Corporation. All rights reserved.
// See the license file in the project root for more information.
using HelloShop.OrderingService.Infrastructure;
using HelloShop.ServiceDefaults.Infrastructure;
namespace HelloShop.OrderingService.DataSeeding
{
public class OrderingDataSeedingProvider(OrderingServiceDbContext dbContext) : IDataSeedingProvider
{
public async Task SeedingAsync(IServiceProvider serviceProvider, CancellationToken cancellationToken = default)
{
await dbContext.Database.EnsureCreatedAsync(cancellationToken);
}
}
}

View File

@ -0,0 +1,14 @@
// Copyright (c) HelloShop Corporation. All rights reserved.
// See the license file in the project root for more information.
namespace HelloShop.OrderingService.Entities.Buyers
{
public class Buyer
{
public int Id { get; set; }
public required string Name { get; set; }
public List<PaymentMethod>? PaymentMethods { get; set; }
}
}

View File

@ -0,0 +1,22 @@
// Copyright (c) HelloShop Corporation. All rights reserved.
// See the license file in the project root for more information.
namespace HelloShop.OrderingService.Entities.Buyers
{
public class PaymentMethod
{
public int Id { get; set; }
public int BuyerId { get; set; }
public required string Alias { get; set; }
public required string CardNumber { get; set; }
public required string CardHolderName { get; set; }
public string? SecurityNumber { get; set; }
public DateTimeOffset? Expiration { get; set; }
}
}

View File

@ -0,0 +1,33 @@
// Copyright (c) HelloShop Corporation. All rights reserved.
// See the license file in the project root for more information.
namespace HelloShop.OrderingService.Entities.Orders
{
public record Address
{
/// <summary>
/// 国家
/// </summary>
public required string Country { get; set; }
/// <summary>
/// 省份
/// </summary>
public required string State { get; set; }
/// <summary>
/// 城市
/// </summary>
public required string City { get; set; }
/// <summary>
/// 街道
/// </summary>
public required string Street { get; set; }
/// <summary>
/// 邮编
/// </summary>
public required string ZipCode { get; set; }
}
}

View File

@ -0,0 +1,40 @@
// Copyright (c) HelloShop Corporation. All rights reserved.
// See the license file in the project root for more information.
using System.Diagnostics.CodeAnalysis;
namespace HelloShop.OrderingService.Entities.Orders
{
public class Order
{
public int Id { get; set; }
public DateTimeOffset OrderDate { get; private set; } = DateTimeOffset.UtcNow;
public required Address Address { get; init; }
public OrderStatus OrderStatus { get; set; } = OrderStatus.Submitted;
public int BuyerId { get; set; }
public int? PaymentMethodId { get; set; }
public required IReadOnlyCollection<OrderItem> OrderItems { get; init; }
public string? Description { get; set; }
/// <summary>
/// EF Core cannot set navigation properties using a constructor.
/// The constructor can be public, private, or have any other accessibility.
/// </summary>
private Order() { }
[SetsRequiredMembers]
public Order(int buyerId, Address address, IEnumerable<OrderItem> orderItems)
{
Address = address;
BuyerId = buyerId;
OrderItems = orderItems.ToList();
}
}
}

View File

@ -0,0 +1,22 @@
// Copyright (c) HelloShop Corporation. All rights reserved.
// See the license file in the project root for more information.
namespace HelloShop.OrderingService.Entities.Orders
{
public class OrderItem
{
public int Id { get; set; }
public int OrderId { get; set; }
public int ProductId { get; set; }
public required string ProductName { get; set; }
public required string PictureUrl { get; set; }
public decimal UnitPrice { get; set; }
public int Units { get; set; }
}
}

View File

@ -0,0 +1,15 @@
// Copyright (c) HelloShop Corporation. All rights reserved.
// See the license file in the project root for more information.
namespace HelloShop.OrderingService.Entities.Orders
{
public enum OrderStatus
{
Submitted = 1,
AwaitingValidation = 2,
StockConfirmed = 3,
Paid = 4,
Shipped = 5,
Cancelled = 6
}
}

View File

@ -0,0 +1,30 @@
// Copyright (c) HelloShop Corporation. All rights reserved.
// See the license file in the project root for more information.
using HelloShop.OrderingService.Constants;
using HelloShop.OrderingService.Infrastructure;
using HelloShop.ServiceDefaults.Extensions;
using Microsoft.EntityFrameworkCore;
namespace HelloShop.OrderingService.Extensions
{
public static class Extensions
{
public static void AddApplicationServices(this IHostApplicationBuilder builder)
{
builder.Services.AddDataSeedingProviders();
builder.Services.AddDbContext<OrderingServiceDbContext>(options =>
{
options.UseNpgsql(builder.Configuration.GetConnectionString(DbConstants.MasterConnectionStringName));
});
}
public static WebApplication MapApplicationEndpoints(this WebApplication app)
{
app.UseDataSeedingProviders();
return app;
}
}
}

View File

@ -7,4 +7,12 @@
<ItemGroup>
<ProjectReference Include="..\HelloShop.ServiceDefaults\HelloShop.ServiceDefaults.csproj" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="8.0.8" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="8.0.8">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="8.0.4" />
</ItemGroup>
</Project>

View File

@ -0,0 +1,19 @@
// Copyright (c) HelloShop Corporation. All rights reserved.
// See the license file in the project root for more information.
using HelloShop.OrderingService.Entities.Buyers;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
namespace HelloShop.OrderingService.Infrastructure.EntityConfigurations.Buyers
{
public class BuyerEntityTypeConfiguration : IEntityTypeConfiguration<Buyer>
{
public void Configure(EntityTypeBuilder<Buyer> builder)
{
builder.ToTable("Buyer");
builder.Property(x => x.Name).HasMaxLength(16).IsRequired();
builder.HasMany(b => b.PaymentMethods).WithOne().HasForeignKey(x => x.BuyerId).OnDelete(DeleteBehavior.Cascade);
}
}
}

View File

@ -0,0 +1,22 @@
// Copyright (c) HelloShop Corporation. All rights reserved.
// See the license file in the project root for more information.
using HelloShop.OrderingService.Entities.Buyers;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
namespace HelloShop.OrderingService.Infrastructure.EntityConfigurations.Buyers
{
public class PaymentMethodEntityTypeConfiguration : IEntityTypeConfiguration<PaymentMethod>
{
public void Configure(EntityTypeBuilder<PaymentMethod> builder)
{
builder.ToTable("PaymentMethods");
builder.Property(x => x.Alias).HasMaxLength(16);
builder.Property(x => x.CardNumber).HasMaxLength(16);
builder.Property(x => x.CardHolderName).HasMaxLength(16);
builder.Property(x => x.SecurityNumber).HasMaxLength(6);
}
}
}

View File

@ -0,0 +1,34 @@
// Copyright (c) HelloShop Corporation. All rights reserved.
// See the license file in the project root for more information.
using HelloShop.OrderingService.Entities.Buyers;
using HelloShop.OrderingService.Entities.Orders;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
namespace HelloShop.OrderingService.Infrastructure.EntityConfigurations.Orders
{
public class OrderEntityTypeConfiguration : IEntityTypeConfiguration<Order>
{
public void Configure(EntityTypeBuilder<Order> builder)
{
builder.ToTable("Orders");
builder.Property(x => x.Description).HasMaxLength(64);
builder.Property(x => x.OrderStatus).HasConversion<string>();
builder.OwnsOne(x => x.Address, ownedAddress =>
{
ownedAddress.Property(x => x.Country).HasColumnName(nameof(Address.Country)).HasMaxLength(8).IsRequired();
ownedAddress.Property(x => x.State).HasColumnName(nameof(Address.State)).HasMaxLength(16).IsRequired();
ownedAddress.Property(x => x.City).HasColumnName(nameof(Address.City)).HasMaxLength(16).IsRequired();
ownedAddress.Property(x => x.Street).HasColumnName(nameof(Address.Street)).HasMaxLength(32).IsRequired();
ownedAddress.Property(x => x.ZipCode).HasColumnName(nameof(Address.ZipCode)).HasMaxLength(6).IsRequired();
});
builder.HasOne<Buyer>().WithMany().HasForeignKey(x => x.BuyerId).OnDelete(DeleteBehavior.Cascade);
builder.HasMany(x => x.OrderItems).WithOne().HasForeignKey(x => x.OrderId).OnDelete(DeleteBehavior.Cascade);
builder.HasOne<PaymentMethod>().WithMany().HasForeignKey(x => x.PaymentMethodId).OnDelete(DeleteBehavior.Restrict);
}
}
}

View File

@ -0,0 +1,20 @@
// Copyright (c) HelloShop Corporation. All rights reserved.
// See the license file in the project root for more information.
using HelloShop.OrderingService.Entities.Orders;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
namespace HelloShop.OrderingService.Infrastructure.EntityConfigurations.Orders
{
public class OrderItemEntityTypeConfiguration : IEntityTypeConfiguration<OrderItem>
{
public void Configure(EntityTypeBuilder<OrderItem> builder)
{
builder.ToTable("OrderItems");
builder.Property(x => x.ProductName).HasMaxLength(16);
builder.Property(x => x.PictureUrl).HasMaxLength(256);
}
}
}

View File

@ -0,0 +1,247 @@
// <auto-generated />
using System;
using HelloShop.OrderingService.Infrastructure;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
#nullable disable
namespace HelloShop.OrderingService.Infrastructure.Migrations
{
[DbContext(typeof(OrderingServiceDbContext))]
[Migration("20240829142135_InitialCreate")]
partial class InitialCreate
{
/// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "8.0.8")
.HasAnnotation("Relational:MaxIdentifierLength", 63);
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
modelBuilder.Entity("HelloShop.OrderingService.Entities.Buyers.Buyer", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<string>("Name")
.IsRequired()
.HasMaxLength(16)
.HasColumnType("character varying(16)");
b.HasKey("Id");
b.ToTable("Buyer", (string)null);
});
modelBuilder.Entity("HelloShop.OrderingService.Entities.Buyers.PaymentMethod", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<string>("Alias")
.IsRequired()
.HasMaxLength(16)
.HasColumnType("character varying(16)");
b.Property<int>("BuyerId")
.HasColumnType("integer");
b.Property<string>("CardHolderName")
.IsRequired()
.HasMaxLength(16)
.HasColumnType("character varying(16)");
b.Property<string>("CardNumber")
.IsRequired()
.HasMaxLength(16)
.HasColumnType("character varying(16)");
b.Property<DateTimeOffset?>("Expiration")
.HasColumnType("timestamp with time zone");
b.Property<string>("SecurityNumber")
.HasMaxLength(6)
.HasColumnType("character varying(6)");
b.HasKey("Id");
b.HasIndex("BuyerId");
b.ToTable("PaymentMethods", (string)null);
});
modelBuilder.Entity("HelloShop.OrderingService.Entities.Orders.Order", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<int>("BuyerId")
.HasColumnType("integer");
b.Property<string>("Description")
.HasMaxLength(64)
.HasColumnType("character varying(64)");
b.Property<DateTimeOffset>("OrderDate")
.HasColumnType("timestamp with time zone");
b.Property<string>("OrderStatus")
.IsRequired()
.HasColumnType("text");
b.Property<int?>("PaymentMethodId")
.HasColumnType("integer");
b.HasKey("Id");
b.HasIndex("BuyerId");
b.HasIndex("PaymentMethodId");
b.ToTable("Orders", (string)null);
});
modelBuilder.Entity("HelloShop.OrderingService.Entities.Orders.OrderItem", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<int>("OrderId")
.HasColumnType("integer");
b.Property<string>("PictureUrl")
.IsRequired()
.HasMaxLength(256)
.HasColumnType("character varying(256)");
b.Property<int>("ProductId")
.HasColumnType("integer");
b.Property<string>("ProductName")
.IsRequired()
.HasMaxLength(16)
.HasColumnType("character varying(16)");
b.Property<decimal>("UnitPrice")
.HasColumnType("numeric");
b.Property<int>("Units")
.HasColumnType("integer");
b.HasKey("Id");
b.HasIndex("OrderId");
b.ToTable("OrderItems", (string)null);
});
modelBuilder.Entity("HelloShop.OrderingService.Entities.Buyers.PaymentMethod", b =>
{
b.HasOne("HelloShop.OrderingService.Entities.Buyers.Buyer", null)
.WithMany("PaymentMethods")
.HasForeignKey("BuyerId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("HelloShop.OrderingService.Entities.Orders.Order", b =>
{
b.HasOne("HelloShop.OrderingService.Entities.Buyers.Buyer", null)
.WithMany()
.HasForeignKey("BuyerId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("HelloShop.OrderingService.Entities.Buyers.PaymentMethod", null)
.WithMany()
.HasForeignKey("PaymentMethodId")
.OnDelete(DeleteBehavior.Restrict);
b.OwnsOne("HelloShop.OrderingService.Entities.Orders.Address", "Address", b1 =>
{
b1.Property<int>("OrderId")
.HasColumnType("integer");
b1.Property<string>("City")
.IsRequired()
.HasMaxLength(16)
.HasColumnType("character varying(16)")
.HasColumnName("City");
b1.Property<string>("Country")
.IsRequired()
.HasMaxLength(8)
.HasColumnType("character varying(8)")
.HasColumnName("Country");
b1.Property<string>("State")
.IsRequired()
.HasMaxLength(16)
.HasColumnType("character varying(16)")
.HasColumnName("State");
b1.Property<string>("Street")
.IsRequired()
.HasMaxLength(32)
.HasColumnType("character varying(32)")
.HasColumnName("Street");
b1.Property<string>("ZipCode")
.IsRequired()
.HasMaxLength(6)
.HasColumnType("character varying(6)")
.HasColumnName("ZipCode");
b1.HasKey("OrderId");
b1.ToTable("Orders");
b1.WithOwner()
.HasForeignKey("OrderId");
});
b.Navigation("Address")
.IsRequired();
});
modelBuilder.Entity("HelloShop.OrderingService.Entities.Orders.OrderItem", b =>
{
b.HasOne("HelloShop.OrderingService.Entities.Orders.Order", null)
.WithMany("OrderItems")
.HasForeignKey("OrderId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("HelloShop.OrderingService.Entities.Buyers.Buyer", b =>
{
b.Navigation("PaymentMethods");
});
modelBuilder.Entity("HelloShop.OrderingService.Entities.Orders.Order", b =>
{
b.Navigation("OrderItems");
});
#pragma warning restore 612, 618
}
}
}

View File

@ -0,0 +1,149 @@
// Copyright (c) HelloShop Corporation. All rights reserved.
// See the license file in the project root for more information.
using Microsoft.EntityFrameworkCore.Migrations;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
#nullable disable
namespace HelloShop.OrderingService.Infrastructure.Migrations
{
/// <inheritdoc />
public partial class InitialCreate : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "Buyer",
columns: table => new
{
Id = table.Column<int>(type: "integer", nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
Name = table.Column<string>(type: "character varying(16)", maxLength: 16, nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_Buyer", x => x.Id);
});
migrationBuilder.CreateTable(
name: "PaymentMethods",
columns: table => new
{
Id = table.Column<int>(type: "integer", nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
BuyerId = table.Column<int>(type: "integer", nullable: false),
Alias = table.Column<string>(type: "character varying(16)", maxLength: 16, nullable: false),
CardNumber = table.Column<string>(type: "character varying(16)", maxLength: 16, nullable: false),
CardHolderName = table.Column<string>(type: "character varying(16)", maxLength: 16, nullable: false),
SecurityNumber = table.Column<string>(type: "character varying(6)", maxLength: 6, nullable: true),
Expiration = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_PaymentMethods", x => x.Id);
table.ForeignKey(
name: "FK_PaymentMethods_Buyer_BuyerId",
column: x => x.BuyerId,
principalTable: "Buyer",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateTable(
name: "Orders",
columns: table => new
{
Id = table.Column<int>(type: "integer", nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
OrderDate = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false),
Country = table.Column<string>(type: "character varying(8)", maxLength: 8, nullable: false),
State = table.Column<string>(type: "character varying(16)", maxLength: 16, nullable: false),
City = table.Column<string>(type: "character varying(16)", maxLength: 16, nullable: false),
Street = table.Column<string>(type: "character varying(32)", maxLength: 32, nullable: false),
ZipCode = table.Column<string>(type: "character varying(6)", maxLength: 6, nullable: false),
OrderStatus = table.Column<string>(type: "text", nullable: false),
BuyerId = table.Column<int>(type: "integer", nullable: false),
PaymentMethodId = table.Column<int>(type: "integer", nullable: true),
Description = table.Column<string>(type: "character varying(64)", maxLength: 64, nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_Orders", x => x.Id);
table.ForeignKey(
name: "FK_Orders_Buyer_BuyerId",
column: x => x.BuyerId,
principalTable: "Buyer",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
table.ForeignKey(
name: "FK_Orders_PaymentMethods_PaymentMethodId",
column: x => x.PaymentMethodId,
principalTable: "PaymentMethods",
principalColumn: "Id",
onDelete: ReferentialAction.Restrict);
});
migrationBuilder.CreateTable(
name: "OrderItems",
columns: table => new
{
Id = table.Column<int>(type: "integer", nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
OrderId = table.Column<int>(type: "integer", nullable: false),
ProductId = table.Column<int>(type: "integer", nullable: false),
ProductName = table.Column<string>(type: "character varying(16)", maxLength: 16, nullable: false),
PictureUrl = table.Column<string>(type: "character varying(256)", maxLength: 256, nullable: false),
UnitPrice = table.Column<decimal>(type: "numeric", nullable: false),
Units = table.Column<int>(type: "integer", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_OrderItems", x => x.Id);
table.ForeignKey(
name: "FK_OrderItems_Orders_OrderId",
column: x => x.OrderId,
principalTable: "Orders",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateIndex(
name: "IX_OrderItems_OrderId",
table: "OrderItems",
column: "OrderId");
migrationBuilder.CreateIndex(
name: "IX_Orders_BuyerId",
table: "Orders",
column: "BuyerId");
migrationBuilder.CreateIndex(
name: "IX_Orders_PaymentMethodId",
table: "Orders",
column: "PaymentMethodId");
migrationBuilder.CreateIndex(
name: "IX_PaymentMethods_BuyerId",
table: "PaymentMethods",
column: "BuyerId");
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "OrderItems");
migrationBuilder.DropTable(
name: "Orders");
migrationBuilder.DropTable(
name: "PaymentMethods");
migrationBuilder.DropTable(
name: "Buyer");
}
}
}

View File

@ -0,0 +1,244 @@
// <auto-generated />
using System;
using HelloShop.OrderingService.Infrastructure;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
#nullable disable
namespace HelloShop.OrderingService.Infrastructure.Migrations
{
[DbContext(typeof(OrderingServiceDbContext))]
partial class OrderingServiceDbContextModelSnapshot : ModelSnapshot
{
protected override void BuildModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "8.0.8")
.HasAnnotation("Relational:MaxIdentifierLength", 63);
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
modelBuilder.Entity("HelloShop.OrderingService.Entities.Buyers.Buyer", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<string>("Name")
.IsRequired()
.HasMaxLength(16)
.HasColumnType("character varying(16)");
b.HasKey("Id");
b.ToTable("Buyer", (string)null);
});
modelBuilder.Entity("HelloShop.OrderingService.Entities.Buyers.PaymentMethod", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<string>("Alias")
.IsRequired()
.HasMaxLength(16)
.HasColumnType("character varying(16)");
b.Property<int>("BuyerId")
.HasColumnType("integer");
b.Property<string>("CardHolderName")
.IsRequired()
.HasMaxLength(16)
.HasColumnType("character varying(16)");
b.Property<string>("CardNumber")
.IsRequired()
.HasMaxLength(16)
.HasColumnType("character varying(16)");
b.Property<DateTimeOffset?>("Expiration")
.HasColumnType("timestamp with time zone");
b.Property<string>("SecurityNumber")
.HasMaxLength(6)
.HasColumnType("character varying(6)");
b.HasKey("Id");
b.HasIndex("BuyerId");
b.ToTable("PaymentMethods", (string)null);
});
modelBuilder.Entity("HelloShop.OrderingService.Entities.Orders.Order", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<int>("BuyerId")
.HasColumnType("integer");
b.Property<string>("Description")
.HasMaxLength(64)
.HasColumnType("character varying(64)");
b.Property<DateTimeOffset>("OrderDate")
.HasColumnType("timestamp with time zone");
b.Property<string>("OrderStatus")
.IsRequired()
.HasColumnType("text");
b.Property<int?>("PaymentMethodId")
.HasColumnType("integer");
b.HasKey("Id");
b.HasIndex("BuyerId");
b.HasIndex("PaymentMethodId");
b.ToTable("Orders", (string)null);
});
modelBuilder.Entity("HelloShop.OrderingService.Entities.Orders.OrderItem", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<int>("OrderId")
.HasColumnType("integer");
b.Property<string>("PictureUrl")
.IsRequired()
.HasMaxLength(256)
.HasColumnType("character varying(256)");
b.Property<int>("ProductId")
.HasColumnType("integer");
b.Property<string>("ProductName")
.IsRequired()
.HasMaxLength(16)
.HasColumnType("character varying(16)");
b.Property<decimal>("UnitPrice")
.HasColumnType("numeric");
b.Property<int>("Units")
.HasColumnType("integer");
b.HasKey("Id");
b.HasIndex("OrderId");
b.ToTable("OrderItems", (string)null);
});
modelBuilder.Entity("HelloShop.OrderingService.Entities.Buyers.PaymentMethod", b =>
{
b.HasOne("HelloShop.OrderingService.Entities.Buyers.Buyer", null)
.WithMany("PaymentMethods")
.HasForeignKey("BuyerId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("HelloShop.OrderingService.Entities.Orders.Order", b =>
{
b.HasOne("HelloShop.OrderingService.Entities.Buyers.Buyer", null)
.WithMany()
.HasForeignKey("BuyerId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("HelloShop.OrderingService.Entities.Buyers.PaymentMethod", null)
.WithMany()
.HasForeignKey("PaymentMethodId")
.OnDelete(DeleteBehavior.Restrict);
b.OwnsOne("HelloShop.OrderingService.Entities.Orders.Address", "Address", b1 =>
{
b1.Property<int>("OrderId")
.HasColumnType("integer");
b1.Property<string>("City")
.IsRequired()
.HasMaxLength(16)
.HasColumnType("character varying(16)")
.HasColumnName("City");
b1.Property<string>("Country")
.IsRequired()
.HasMaxLength(8)
.HasColumnType("character varying(8)")
.HasColumnName("Country");
b1.Property<string>("State")
.IsRequired()
.HasMaxLength(16)
.HasColumnType("character varying(16)")
.HasColumnName("State");
b1.Property<string>("Street")
.IsRequired()
.HasMaxLength(32)
.HasColumnType("character varying(32)")
.HasColumnName("Street");
b1.Property<string>("ZipCode")
.IsRequired()
.HasMaxLength(6)
.HasColumnType("character varying(6)")
.HasColumnName("ZipCode");
b1.HasKey("OrderId");
b1.ToTable("Orders");
b1.WithOwner()
.HasForeignKey("OrderId");
});
b.Navigation("Address")
.IsRequired();
});
modelBuilder.Entity("HelloShop.OrderingService.Entities.Orders.OrderItem", b =>
{
b.HasOne("HelloShop.OrderingService.Entities.Orders.Order", null)
.WithMany("OrderItems")
.HasForeignKey("OrderId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("HelloShop.OrderingService.Entities.Buyers.Buyer", b =>
{
b.Navigation("PaymentMethods");
});
modelBuilder.Entity("HelloShop.OrderingService.Entities.Orders.Order", b =>
{
b.Navigation("OrderItems");
});
#pragma warning restore 612, 618
}
}
}

View File

@ -0,0 +1,18 @@
// Copyright (c) HelloShop Corporation. All rights reserved.
// See the license file in the project root for more information.
using Microsoft.EntityFrameworkCore;
using System.Reflection;
namespace HelloShop.OrderingService.Infrastructure
{
public partial class OrderingServiceDbContext(DbContextOptions<OrderingServiceDbContext> options) : DbContext(options)
{
protected override void OnModelCreating(ModelBuilder builder)
{
base.OnModelCreating(builder);
builder.ApplyConfigurationsFromAssembly(Assembly.GetExecutingAssembly());
}
}
}

View File

@ -0,0 +1,6 @@
```shell
dotnet ef database drop --force
dotnet ef migrations remove
dotnet ef migrations add InitialCreate --output-dir Infrastructure/Migrations
dotnet ef database update
```

View File

@ -1,27 +1,22 @@
// Copyright (c) HelloShop Corporation. All rights reserved.
// See the license file in the project root for more information.
using HelloShop.ServiceDefaults.Extensions;
using HelloShop.OrderingService.Extensions;
var builder = WebApplication.CreateBuilder(args);
builder.AddServiceDefaults();
// Add services to the container.
builder.AddServiceDefaults();
builder.AddApplicationServices();
builder.Services.AddControllers();
builder.Services.AddOpenApi();
var app = builder.Build();
// Configure the HTTP request pipeline.
app.MapDefaultEndpoints();
app.UseAuthorization();
app.UseCors(options => options.AllowAnyOrigin().AllowAnyMethod().AllowAnyHeader());
app.MapApplicationEndpoints();
app.MapControllers();
app.UseOpenApi();
app.Run();

View File

@ -5,5 +5,9 @@
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*"
"AllowedHosts": "*",
"ConnectionStrings": {
"OrderingDatabaseMaster": "Host=localhost;Port=5432;Database=OrderingService;Username=postgres;Password=postgres",
"OrderingDatabaseSlave": "Host=localhost;Port=5432;Database=OrderingService;Username=postgres;Password=postgres"
}
}

View File

@ -3,7 +3,7 @@
using AutoMapper;
using HelloShop.ProductService.Entities.Products;
using HelloShop.ProductService.EntityFrameworks;
using HelloShop.ProductService.Infrastructure;
using HelloShop.ProductService.Models.Products;
using HelloShop.ProductService.PermissionProviders;
using HelloShop.ServiceDefaults.Extensions;
@ -12,7 +12,7 @@ using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
namespace HelloShop.ProductService;
namespace HelloShop.ProductService.Controllers;
[Route("api/[controller]")]
[ApiController]
public class BrandsController(ProductServiceDbContext dbContext, IMapper mapper) : ControllerBase

View File

@ -3,7 +3,7 @@
using AutoMapper;
using HelloShop.ProductService.Entities.Products;
using HelloShop.ProductService.EntityFrameworks;
using HelloShop.ProductService.Infrastructure;
using HelloShop.ProductService.Models.Products;
using HelloShop.ProductService.PermissionProviders;
using HelloShop.ServiceDefaults.Extensions;
@ -12,7 +12,7 @@ using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
namespace HelloShop.ProductService;
namespace HelloShop.ProductService.Controllers;
[Route("api/[controller]")]
[ApiController]

View File

@ -2,14 +2,14 @@
// See the license file in the project root for more information.
using HelloShop.ProductService.Entities.Products;
using HelloShop.ProductService.EntityFrameworks;
using HelloShop.ProductService.Infrastructure;
using HelloShop.ServiceDefaults.Infrastructure;
namespace HelloShop.ProductService.DataSeeding
{
public class ProductDataSeedingProvider(ProductServiceDbContext dbContext) : IDataSeedingProvider
{
public async Task SeedingAsync(IServiceProvider ServiceProvider)
public async Task SeedingAsync(IServiceProvider ServiceProvider, CancellationToken cancellationToken = default)
{
if (!dbContext.Set<Product>().Any())
{
@ -82,16 +82,16 @@ namespace HelloShop.ProductService.DataSeeding
{
var brand = new Brand { Name = brandName };
await dbContext.AddAsync(brand);
await dbContext.AddAsync(brand, cancellationToken);
foreach (var product in productList)
{
product.Brand = brand;
await dbContext.AddAsync(product);
await dbContext.AddAsync(product, cancellationToken);
}
}
await dbContext.SaveChangesAsync();
await dbContext.SaveChangesAsync(cancellationToken);
}
}
}

View File

@ -5,7 +5,7 @@ using HelloShop.ProductService.Entities.Products;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
namespace HelloShop.ProductService.EntityFrameworks.EntityConfigurations.Products;
namespace HelloShop.ProductService.Infrastructure.EntityConfigurations.Products;
public class BrandEntityTypeConfiguration : IEntityTypeConfiguration<Brand>
{

View File

@ -5,7 +5,7 @@ using HelloShop.ProductService.Entities.Products;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
namespace HelloShop.ProductService.EntityFrameworks.EntityConfigurations.Products;
namespace HelloShop.ProductService.Infrastructure.EntityConfigurations.Products;
public class ProductEntityTypeConfiguration : IEntityTypeConfiguration<Product>
{

View File

@ -1,6 +1,6 @@
// <auto-generated />
using System;
using HelloShop.ProductService.EntityFrameworks;
using HelloShop.ProductService.Infrastructure;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;

View File

@ -1,6 +1,6 @@
// <auto-generated />
using System;
using HelloShop.ProductService.EntityFrameworks;
using HelloShop.ProductService.Infrastructure;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;

View File

@ -4,7 +4,7 @@
using Microsoft.EntityFrameworkCore;
using System.Reflection;
namespace HelloShop.ProductService.EntityFrameworks;
namespace HelloShop.ProductService.Infrastructure;
public class ProductServiceDbContext(DbContextOptions<ProductServiceDbContext> options) : DbContext(options)
{

View File

@ -2,7 +2,7 @@
// See the license file in the project root for more information.
using HelloShop.ProductService.Constants;
using HelloShop.ProductService.EntityFrameworks;
using HelloShop.ProductService.Infrastructure;
using HelloShop.ServiceDefaults.Extensions;
using Microsoft.EntityFrameworkCore;

View File

@ -6,7 +6,7 @@ using HelloShop.ProductService.Entities.Products;
// Copyright (c) HelloShop Corporation. All rights reserved.
// See the license file in the project root for more information.
using HelloShop.ProductService.EntityFrameworks;
using HelloShop.ProductService.Infrastructure;
using Microsoft.EntityFrameworkCore;
namespace HelloShop.ProductService.Services

View File

@ -7,6 +7,6 @@ namespace HelloShop.ServiceDefaults.Infrastructure
{
int Order => default;
Task SeedingAsync(IServiceProvider serviceProvider);
Task SeedingAsync(IServiceProvider serviceProvider, CancellationToken cancellationToken = default);
}
}

View File

@ -1,7 +1,7 @@
// Copyright (c) HelloShop Corporation. All rights reserved.
// See the license file in the project root for more information.
using HelloShop.ProductService.EntityFrameworks;
using HelloShop.ProductService.Infrastructure;
using HelloShop.ServiceDefaults.Authorization;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc.Testing;

View File

@ -3,7 +3,9 @@
using AutoMapper;
using HelloShop.ProductService.AutoMapper;
using HelloShop.ProductService.Controllers;
using HelloShop.ProductService.Entities.Products;
using HelloShop.ProductService.Infrastructure;
using HelloShop.ProductService.Models.Products;
using HelloShop.ProductService.UnitTests.Utilities;
using Microsoft.AspNetCore.Mvc;
@ -16,7 +18,7 @@ namespace HelloShop.ProductService.UnitTests
public async Task GetProductByIdReturnsProductDetailsResponse()
{
// Arrange
await using EntityFrameworks.ProductServiceDbContext dbContext = new FakeDbContextFactory().CreateDbContext();
await using ProductServiceDbContext dbContext = new FakeDbContextFactory().CreateDbContext();
await dbContext.AddAsync(new Product { Id = 1, Name = "Product 1", Price = 10 });
@ -40,7 +42,7 @@ namespace HelloShop.ProductService.UnitTests
public async Task PostProductReturnsProductDetailsResponse(string productName, decimal price)
{
// Arrange
await using EntityFrameworks.ProductServiceDbContext dbContext = new FakeDbContextFactory().CreateDbContext();
await using ProductServiceDbContext dbContext = new FakeDbContextFactory().CreateDbContext();
IMapper mapper = new MapperConfiguration(configure => configure.AddProfile<ProductsMapConfiguration>()).CreateMapper();

View File

@ -1,7 +1,7 @@
// Copyright (c) HelloShop Corporation. All rights reserved.
// See the license file in the project root for more information.
using HelloShop.ProductService.EntityFrameworks;
using HelloShop.ProductService.Infrastructure;
using Microsoft.EntityFrameworkCore;
namespace HelloShop.ProductService.UnitTests.Utilities