Infrastructure

This commit is contained in:
2026-04-22 20:51:02 +04:30
parent c64c3dd9be
commit 64ee78e320
199 changed files with 7428 additions and 1027 deletions
@@ -0,0 +1,10 @@
using System.Reflection;
using Vizhvizh.GoldGallery.Application;
namespace Vizhvizh.GoldGallery.Infrastructure.Configuration;
internal static class Assemblies
{
public static Assembly Application = typeof(IGoldGalleryModule).Assembly;
public static Assembly Infrastructure = typeof(GoldGalleryStartup).Assembly;
}
@@ -0,0 +1,52 @@
using Microsoft.Extensions.DependencyInjection;
using Vizhvizh.BuildingBlocks.Application.Configuration.Commnad;
using Vizhvizh.BuildingBlocks.Application.Configuration.Query;
using Vizhvizh.BuildingBlocks.Application.Contract;
using Vizhvizh.BuildingBlocks.Domain;
using Vizhvizh.BuildingBlocks.Domain.Contract;
using Vizhvizh.BuildingBlocks.Infrastructure;
namespace Vizhvizh.GoldGallery.Infrastructure.Configuration;
public class Executor : IExecutor
{
private readonly IServiceProvider _serviceProvider;
public Executor(IServiceProvider serviceProvider)
{
_serviceProvider = serviceProvider;
}
public async Task Execute(ICommand command, CancellationToken cancellationToken)
{
var handlerType = typeof(ICommandHandler<>).MakeGenericType(command.GetType());
var handler = _serviceProvider.GetRequiredService(handlerType);
dynamic dynamicHandler = handler;
dynamic dynamicCommand = command;
await dynamicHandler.Handle(dynamicCommand, cancellationToken);
}
public async Task<TResult> Execute<TResult>(ICommand<TResult> command, CancellationToken cancellationToken)
{
var handlerType = typeof(ICommandHandler<,>).MakeGenericType(command.GetType(),typeof(TResult));
var handler = _serviceProvider.GetRequiredService(handlerType);
dynamic dynamicHandler = handler;
dynamic dynamicCommand = command;
return await dynamicHandler.Handle(dynamicCommand, cancellationToken);
}
public async Task<TResult> Execute<TResult>(IQuery<TResult> query, CancellationToken cancellationToken)
{
var handlerType = typeof(IQueryHandler<,>).MakeGenericType(query.GetType(), typeof(TResult));
var handler = _serviceProvider.GetRequiredService(handlerType);
dynamic dynamicHandler = handler;
dynamic dynamicQuery = query;
return await dynamicHandler.Handle(dynamicQuery, cancellationToken);
}
public async Task Execute(IDomainEvent notification, CancellationToken cancellationToken = default)
{
var handlerType = typeof(INotificationHandler<>).MakeGenericType(notification.GetType());
var handler = _serviceProvider.GetRequiredService(handlerType);
dynamic dynamicHandler = handler;
dynamic dynamicNotification = notification;
await dynamicHandler.Handle(dynamicNotification, cancellationToken);
}
}
@@ -0,0 +1,29 @@
using Vizhvizh.GoldGallery.Application;
using Vizhvizh.BuildingBlocks.Application.Contract;
using Vizhvizh.BuildingBlocks.Domain.Contract;
using Vizhvizh.BuildingBlocks.Infrastructure;
namespace Vizhvizh.GoldGallery.Infrastructure.Configuration;
internal class GoldGalleryModule : IGoldGalleryModule
{
private readonly IExecutor _executor;
public GoldGalleryModule(IExecutor executor)
{
_executor = executor;
}
public async Task<TResult> ExecuteCommandAsync<TResult>(ICommand<TResult> command, CancellationToken cancellationToken)
{
return await _executor.Execute(command, cancellationToken);
}
public async Task ExecuteCommandAsync(ICommand command, CancellationToken cancellationToken)
{
await _executor.Execute(command, cancellationToken);
}
public async Task<TResult> ExecuteQueryAsync<TResult>(IQuery<TResult> query, CancellationToken cancellationToken)
{
return await _executor.Execute(query, cancellationToken);
}
}
@@ -0,0 +1,63 @@
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
using Vizhvizh.GoldGallery.Domain.Products.Entities;
using Vizhvizh.GoldGallery.Domain.Products.TypeIds;
using Vizhvizh.GoldGallery.Domain.Products.ValuesObjects;
namespace Vizhvizh.GoldGallery.Infrastructure.EF.Configurations;
internal class CategoryConfiguration : BaseEntityConfiguration<Category, CategoryId, long>
{
public override void Configure(EntityTypeBuilder<Category> builder)
{
base.Configure(builder);
builder.ToTable("Categories", schema: "GoldGallery");
builder.Property(x => x.Title)
.HasField("_title")
.IsRequired();
builder.Property(x => x.Description)
.IsRequired(false)
.HasField("_description");
builder.Property(x => x.ParentId)
.HasConversion(x => x.Value, x => new Domain.Products.TypeIds.CategoryId(x))
.IsRequired(false)
.HasField("_parentId");
builder.OwnsOne(x => x.Image, sa =>
{
sa.Property(x => x.Value)
.HasMaxLength(CategoryImage.Limit)
.HasColumnName("Image");
});
builder.Property(x => x.Path)
.HasField("_path")
.IsRequired()
.HasConversion(x => x.Value, x => Domain.Products.ValuesObjects.CategoryPath.CreateNew(x))
.HasColumnType("HIERARCHYID");
// ایندکس برای Path با نوع HIERARCHYID
builder.HasIndex(x => x.Path)
.HasDatabaseName("IX_Categories_Path")
.IsClustered(false); // معمولاً برای HierarchyId بهتر است non-clustered باشد
// رابطه خودارجاع برای ParentId
builder.HasOne<Category>()
.WithMany()
.HasForeignKey(x => x.ParentId)
.HasConstraintName("FK_Categories_ParentId")
.OnDelete(DeleteBehavior.Restrict)
.IsRequired(false);
// ایندکس برای ParentId جهت بهبود performance در کوئری‌های سلسله مراتبی
builder.HasIndex(x => x.ParentId)
.HasDatabaseName("IX_Categories_ParentId");
builder.Metadata.FindNavigation(nameof(Category.Products))?
.SetPropertyAccessMode(PropertyAccessMode.Field);
}
}
@@ -0,0 +1,13 @@
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using System.Linq.Expressions;
using Vizhvizh.GoldGallery.Domain.Members.TypeIds;
namespace Vizhvizh.GoldGallery.Infrastructure.EF.Configurations.Converter;
internal class MemberIdConverter : ValueConverter<MemberId, long>
{
public MemberIdConverter()
: base(x=>x.Value, x=> new MemberId(x))
{
}
}
@@ -0,0 +1,14 @@
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using System.Linq.Expressions;
using Vizhvizh.GoldGallery.Domain.Products.ValuesObjects;
namespace Vizhvizh.GoldGallery.Infrastructure.EF.Configurations.Converter;
internal class ProductImageConverter : ValueConverter<ProductImage, string>
{
public ProductImageConverter()
: base(x=>x.Value, x=> ProductImage.CreateNew(x))
{
}
}
@@ -0,0 +1,21 @@
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
using Vizhvizh.GoldGallery.Domain.Shops.Entities;
using Vizhvizh.GoldGallery.Domain.Shops.TypeIds;
namespace Vizhvizh.GoldGallery.Infrastructure.EF.Configurations;
internal class ManagementConfiguration : BaseEntityConfiguration<Management, ShopId, long>
{
public override void Configure(EntityTypeBuilder<Management> builder)
{
base.Configure(builder);
builder.ToTable("Managements", schema: "GoldGallery");
builder.Metadata.FindNavigation(nameof(Management.Shop))?
.SetPropertyAccessMode(PropertyAccessMode.Field);
}
}
@@ -0,0 +1,44 @@
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
using Vizhvizh.GoldGallery.Domain.Members.Entities;
using Vizhvizh.GoldGallery.Domain.Members.TypeIds;
using Vizhvizh.GoldGallery.Domain.Members.ValuesObjects;
namespace Vizhvizh.GoldGallery.Infrastructure.EF.Configurations;
internal class MemberConfiguration : BaseEntityConfiguration<Member, MemberId, long>
{
public override void Configure(EntityTypeBuilder<Member> builder)
{
base.Configure(builder);
builder.ToTable("Members", schema: "GoldGallery");
builder.Property(x => x.PhoneNumber)
.HasField("_phoneNumber");
builder.OwnsOne(x => x.FullName, sa =>
{
sa.Property(x => x.FirstName)
.HasMaxLength(MemberFullName.FirstNameLimit)
.HasColumnName("FirstName");
sa.Property(x => x.LastName)
.HasMaxLength(MemberFullName.LastNameLimit)
.HasColumnName("LastName");
});
builder.OwnsOne(x => x.Avatar, sa =>
{
sa.Property(x => x.Value)
.HasMaxLength(MemberAvatar.Limit)
.HasColumnName("Avatar");
});
builder.OwnsOne(x => x.NationalCode, sa =>
{
sa.Property(x => x.Value)
.IsRequired(false)
.HasMaxLength(MemberNationalCode.Limit)
.HasColumnName("NationalCode");
});
}
}
@@ -0,0 +1,68 @@
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
using System.Drawing;
using Vizhvizh.GoldGallery.Domain.Products.Entities;
using Vizhvizh.GoldGallery.Domain.Products.TypeIds;
using Vizhvizh.GoldGallery.Domain.Products.ValuesObjects;
namespace Vizhvizh.GoldGallery.Infrastructure.EF.Configurations;
internal class ProductConfiguration : BaseEntityConfiguration<Product,ProductId, long>
{
public override void Configure(EntityTypeBuilder<Product> builder)
{
base.Configure(builder);
builder.ToTable("Products", schema: "GoldGallery");
builder.OwnsOne(x => x.ProductCondition, sa =>
{
sa.Property(x => x.Value).HasColumnName("ProductCondition");
});
builder.Property(x => x.Title)
.HasField("_title");
builder.Property(x => x.Description)
.HasField("_description");
builder.OwnsOne(x => x.Score, sa =>
{
sa.Property(x => x.Score).HasColumnType("Score")
.HasColumnType("TINYINT")
.HasDefaultValue(0);
sa.Property(x => x.TotalVoters).HasColumnName("TotalVoters")
.HasColumnType("INT")
.HasDefaultValue(0); ;
});
builder.OwnsOne(x => x.CraftsmanshipFee, sa =>
{
sa.Property(x => x.Value)
.HasColumnType("decimal(4,2)")
.HasColumnName("CraftsmanshipFee");
});
builder.OwnsOne(x => x.Image, sa =>
{
sa.Property(x => x.Value)
.HasMaxLength(ProductImage.Limit)
.HasColumnName("Image");
});
builder.OwnsOne(x => x.File3D, sa =>
{
sa.Property(x => x.Value)
.HasMaxLength(ProductFile3D.Limit)
.HasColumnName("File3D")
.IsRequired(false);
});
builder.Metadata.FindNavigation(nameof(Product.Specifications))?
.SetPropertyAccessMode(PropertyAccessMode.Field);
builder.Metadata.FindNavigation(nameof(Product.Category))?
.SetPropertyAccessMode(PropertyAccessMode.Field);
builder.Metadata.FindNavigation(nameof(Product.Variants))?
.SetPropertyAccessMode(PropertyAccessMode.Field);
}
}
@@ -0,0 +1,50 @@
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
using Vizhvizh.GoldGallery.Domain.Products.Entities;
using Vizhvizh.GoldGallery.Domain.Products.TypeIds;
using Vizhvizh.GoldGallery.Domain.Products.ValuesObjects;
namespace Vizhvizh.GoldGallery.Infrastructure.EF.Configurations;
internal class ProductVariantConfiguration : BaseEntityConfiguration<ProductVariant, ProductVariantId, long>
{
public override void Configure(EntityTypeBuilder<ProductVariant> builder)
{
base.Configure(builder);
builder.ToTable("ProductVariants", schema: "GoldGallery");
builder.OwnsOne(x => x.Score, sa =>
{
sa.Property(x => x.Score)
.HasColumnName("Score")
.HasColumnType("TINYINT")
.HasDefaultValue(0);
sa.Property(x => x.TotalVoters)
.HasColumnName("TotalVoters")
.HasColumnType("INT")
.HasDefaultValue(0);
});
builder.OwnsOne(x => x.Quantity, sa =>
{
sa.Property(x => x.Value).HasColumnName("Quantity");
});
builder.OwnsOne(x => x.Weight, sa =>
{
sa.Property(x => x.Value)
.HasColumnType("decimal(7,3)")
.HasColumnName("Weight");
});
builder.OwnsOne(x => x.Gallery, sa =>
{
sa.Property(x => x.Values).HasColumnName("Gallery");
sa.ToJson();
});
builder.Metadata.FindNavigation(nameof(ProductVariant.Product))?
.SetPropertyAccessMode(PropertyAccessMode.Field);
}
}
@@ -0,0 +1,35 @@
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
using Vizhvizh.Shared.Domain.ValueObjects;
using Vizhvizh.GoldGallery.Domain.Users.Entities;
using Vizhvizh.GoldGallery.Domain.Users.ValueObjects;
using Vizhvizh.GoldGallery.Domain.Users.TypeIds;
namespace Vizhvizh.GoldGallery.Infrastructure.EF.Configurations;
public class ResourceConfiguration : BaseEntityConfiguration<Resource,ResourceId,long>
{
public override void Configure(EntityTypeBuilder<Resource> builder)
{
base.Configure(builder);
builder.ToTable("Resources", schema: "GoldGallery");
builder.Property(x => x.Title)
.HasField("_title");
builder.Property(x => x.Description)
.HasField("_description");
builder.Property(x => x.ModuleName)
.HasField("_moduleName")
.HasColumnType("int")
.HasConversion(x=> (int)x.Value, x=> ModuleNameVO.CreateNew((ModuleNamesEnum)x));
builder.Property(x => x.ResourceKey)
.HasConversion(x=>x.Value, x=> ResourceKey.CreateNew(x))
.HasField("_resourceKey");
builder.Metadata.FindNavigation(nameof(Resource.Roles))?
.SetPropertyAccessMode(PropertyAccessMode.Field);
}
}
@@ -0,0 +1,22 @@
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
using Vizhvizh.GoldGallery.Domain.Users.Entities;
using Vizhvizh.GoldGallery.Domain.Users.TypeIds;
namespace Vizhvizh.GoldGallery.Infrastructure.EF.Configurations;
public class RoleConfiguration : BaseEntityConfiguration<Role,RoleId, int>
{
public override void Configure(EntityTypeBuilder<Role> builder)
{
base.Configure(builder);
builder.ToTable("Roles", schema: "GoldGallery");
builder.Property(x => x.Title)
.HasField("_title");
builder.Metadata.FindNavigation(nameof(Role.RoleResources))?
.SetPropertyAccessMode(PropertyAccessMode.Field);
}
}
@@ -0,0 +1,27 @@
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
using Vizhvizh.GoldGallery.Domain.Users.Entities;
using Vizhvizh.GoldGallery.Domain.Users.TypeIds;
using Vizhvizh.GoldGallery.Domain.Users.ValueObjects;
namespace Vizhvizh.GoldGallery.Infrastructure.EF.Configurations;
public class RoleResourceConfiguration : BaseEntityConfiguration<RoleResource,RoleResourceId, long>
{
public override void Configure(EntityTypeBuilder<RoleResource> builder)
{
base.Configure(builder);
builder.ToTable("RoleResources", schema: "GoldGallery");
builder.Property(x=>x.AccessLevel)
.HasConversion(x=>x.Value, x=> AccessLevel.CreateNew((AccessLevelEnum)x));
builder.Metadata.FindNavigation(nameof(RoleResource.User))?
.SetPropertyAccessMode(PropertyAccessMode.Field);
builder.Metadata.FindNavigation(nameof(RoleResource.Role))?
.SetPropertyAccessMode(PropertyAccessMode.Field);
}
}
@@ -0,0 +1,30 @@
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
using Vizhvizh.GoldGallery.Domain.Shops.Entities;
using Vizhvizh.GoldGallery.Domain.Shops.TypeIds;
using Vizhvizh.GoldGallery.Domain.Shops.ValuesObjects;
namespace Vizhvizh.GoldGallery.Infrastructure.EF.Configurations;
internal class ShippingMethodConfiguration : BaseEntityConfiguration<ShippingMethod, ShippingMethodId, int>
{
public override void Configure(EntityTypeBuilder<ShippingMethod> builder)
{
base.Configure(builder);
builder.ToTable("ShippingMethods", schema: "GoldGallery");
builder.Property(x => x.Title)
.HasField("_title");
builder.Property(x => x.Description)
.HasField("_description");
builder.OwnsOne(x => x.Image, sa =>
{
sa.Property(x => x.Value)
.HasMaxLength(ShippingMethodImage.Limit)
.HasColumnName("Image");
});
builder.Metadata.FindNavigation(nameof(ShippingMethod.Shop))?
.SetPropertyAccessMode(PropertyAccessMode.Field);
}
}
@@ -0,0 +1,69 @@
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
using Vizhvizh.GoldGallery.Domain.Shops.Entities;
using Vizhvizh.GoldGallery.Domain.Shops.TypeIds;
using Vizhvizh.GoldGallery.Domain.Shops.ValuesObjects;
namespace Vizhvizh.GoldGallery.Infrastructure.EF.Configurations;
public class ShopConfiguration : BaseEntityConfiguration<Domain.Shops.Entities.Shop,ShopId,long>
{
public override void Configure(EntityTypeBuilder<Domain.Shops.Entities.Shop> builder)
{
base.Configure(builder);
builder.ToTable("Shops", schema: "GoldGallery");
builder.Property(x => x.OwnerId)
.HasField("_ownerId");
builder.Property(x => x.Title)
.HasField("_title");
builder.Property(x => x.Description)
.HasField("_description");
builder.Property(x => x.Email)
.HasField("_email");
builder.Property(x => x.Telephone)
.HasField("_telephoneVO");
builder.OwnsOne(x => x.Logo, sa =>
{
sa.Property(x => x.Value)
.HasMaxLength(ShopLogo.Limit)
.HasColumnName("Logo");
});
builder.OwnsOne(x => x.BusinessLicense, sa =>
{
sa.Property(x => x.Image)
.HasMaxLength(ShopBusinessLicense.ImageLimit)
.HasColumnName("ShopBusinessLicenseImage");
sa.Property(x => x.Code)
.HasMaxLength(ShopBusinessLicense.CodeLimit)
.HasColumnName("ShopBusinessLicenseCode");
});
builder.OwnsOne(x => x.Location, sa =>
{
sa.Property(x => x.PostalCode).HasColumnName(nameof(ShopLocation.PostalCode));
sa.Property(x => x.ProvinceId).HasColumnName(nameof(ShopLocation.ProvinceId));
sa.Property(x => x.CityId).HasColumnName(nameof(ShopLocation.CityId));
sa.Property(x => x.Address).HasColumnName(nameof(ShopLocation.Address));
sa.Property(x => x.Latitude).HasColumnName(nameof(ShopLocation.Latitude));
sa.Property(x => x.Longitude).HasColumnName(nameof(ShopLocation.Longitude));
sa.ToJson();
});
builder.HasOne(x => x.Management)
.WithOne(x => x.Shop)
.HasForeignKey<Management>(x => x.Id);
builder.Metadata.FindNavigation(nameof(Domain.Shops.Entities.Shop.Management))?
.SetPropertyAccessMode(PropertyAccessMode.Field);
builder.Metadata.FindNavigation(nameof(Domain.Shops.Entities.Shop.Products))?
.SetPropertyAccessMode(PropertyAccessMode.Field);
builder.Metadata.FindNavigation(nameof(Domain.Shops.Entities.Shop.ShippingMethods))?
.SetPropertyAccessMode(PropertyAccessMode.Field);
builder.Metadata.FindNavigation(nameof(Domain.Shops.Entities.Shop.Members))?
.SetPropertyAccessMode(PropertyAccessMode.Field);
}
}
@@ -0,0 +1,44 @@
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
using Vizhvizh.GoldGallery.Domain.Sliders.Entities;
using Vizhvizh.GoldGallery.Domain.Sliders.TypeIds;
using Vizhvizh.GoldGallery.Domain.Sliders.ValuesObjects;
namespace Vizhvizh.GoldGallery.Infrastructure.EF.Configurations;
internal class SliderConfiguration : BaseEntityConfiguration<Slider,SliderId,long>
{
public override void Configure(EntityTypeBuilder<Slider> builder)
{
base.Configure(builder);
builder.ToTable("Sliders", schema: "GoldGallery");
builder.Property(x => x.Title)
.HasField("_title");
builder.OwnsOne(x => x.Image, sa =>
{
sa.Property(x => x.Value)
.HasMaxLength(SliderImage.Limit)
.HasColumnName("Image");
});
builder.OwnsOne(x => x.Url, sa =>
{
sa.Property(x => x.Value)
.HasMaxLength(SliderUrl.Limit)
.HasColumnName("Url");
});
builder.OwnsOne(x => x.Key, sa =>
{
sa.Property(x => x.Value)
.HasColumnName("Key")
.HasMaxLength(SliderKey.Limit);
sa.Property(x => x.Type)
.HasColumnName("Type")
.HasColumnType("INT");
});
}
}
@@ -0,0 +1,27 @@
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
using Newtonsoft.Json;
using Vizhvizh.GoldGallery.Domain.Products.Entities;
using Vizhvizh.GoldGallery.Domain.Products.TypeIds;
namespace Vizhvizh.GoldGallery.Infrastructure.EF.Configurations;
internal class SpecificationsConfiguration : BaseEntityConfiguration<Specifications, SpecificationsId, long>
{
public override void Configure(EntityTypeBuilder<Specifications> builder)
{
base.Configure(builder);
builder.ToTable("ProductSpecifications", schema: "GoldGallery");
builder.Property(x => x.Title)
.HasField("_title");
builder.Property(x => x.ItemValues)
.HasConversion(x=> JsonConvert.SerializeObject(x), x=> JsonConvert.DeserializeObject<List<string>>(x)!)
.HasField("_itemValues");
builder.Metadata.FindNavigation(nameof(Specifications.Product))?
.SetPropertyAccessMode(PropertyAccessMode.Field);
}
}
@@ -0,0 +1,25 @@
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
using Vizhvizh.GoldGallery.Domain.Users.Entities;
using Vizhvizh.GoldGallery.Domain.Users.TypeIds;
namespace Vizhvizh.GoldGallery.Infrastructure.EF.Configurations;
public class UserConfiguration : BaseEntityConfiguration<User, UserId,long>
{
public override void Configure(EntityTypeBuilder<User> builder)
{
base.Configure(builder);
builder.ToTable("Users", schema: "GoldGallery");
//builder.OwnsOne(x => x.NationalCode, sa =>
//{
// sa.Property(x => x.Value).HasColumnName("NationalCode");
//});
builder.Property(x => x.MemberId);
builder.Metadata.FindNavigation(nameof(User.Roles))?
.SetPropertyAccessMode(PropertyAccessMode.Field);
}
}
@@ -0,0 +1,79 @@
using Microsoft.EntityFrameworkCore;
using Microsoft.IdentityModel.Abstractions;
using Vizhvizh.Shared.Domain.ValueObjects;
using Vizhvizh.Shared.Infrastructure.EF.Configurations.Converters;
using Vizhvizh.GoldGallery.Domain.Members.TypeIds;
using Vizhvizh.GoldGallery.Domain.Sliders.Entities;
using Vizhvizh.GoldGallery.Infrastructure.Configuration;
using Vizhvizh.GoldGallery.Infrastructure.EF.Configurations.Converter;
namespace Vizhvizh.GoldGallery.Infrastructure.EF;
internal class GoldGalleryDbContext : DbContext
{
public GoldGalleryDbContext(DbContextOptions<GoldGalleryDbContext> options)
: base(options)
{
}
public virtual DbSet<Domain.Members.Entities.Member> Members { get; set; }
public virtual DbSet<Domain.Products.Entities.Product> Products { get; set; }
public virtual DbSet<Domain.Products.Entities.Category> Categories { get; set; }
public virtual DbSet<Domain.Products.Entities.Specifications> Specifications { get; set; }
public virtual DbSet<Domain.Shops.Entities.Shop> Shops { get; set; }
public virtual DbSet<Slider> Sliders { get; set; }
public virtual DbSet<Domain.Shops.Entities.ShippingMethod> ShippingMethods { get; set; }
public virtual DbSet<Domain.Shops.Entities.Management> Managements { get; set; }
public virtual DbSet<Domain.Users.Entities.User> Users { get; set; }
public virtual DbSet<Domain.Users.Entities.RoleResource> RoleResources { get; set; }
public virtual DbSet<Domain.Users.Entities.Role> Roles { get; set; }
public virtual DbSet<Domain.Users.Entities.Resource> Resources { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.ApplyConfigurationsFromAssembly(Assemblies.Infrastructure, FindConfigurations);
// مرحله 1: ساخت Sequence‌ها
modelBuilder.AddHiLoSequences();
}
public bool FindConfigurations(Type type)
=> type?.FullName?.Contains("Configurations") ?? false;
protected override void ConfigureConventions(ModelConfigurationBuilder configurationBuilder)
{
configurationBuilder.Properties<MemberId>()
.HaveConversion<MemberIdConverter>();
configurationBuilder.Properties<DateTimeVO>()
.HaveConversion<DateTimeConverter>();
configurationBuilder.Properties<TitleVO>()
.HaveConversion<TitleConverter>()
.HaveMaxLength(TitleVO.Limit);
configurationBuilder.Properties<DescriptionVO>()
.HaveConversion<DescriptionConverter>()
.HaveMaxLength(DescriptionVO.Limit);
configurationBuilder.Properties<EmailVO>()
.HaveMaxLength(EmailVO.Limit)
.HaveConversion<EmailConverter>();
configurationBuilder.Properties<PhoneNumberVO>()
.HaveConversion<PhoneNumberConverter>()
.HaveMaxLength(PhoneNumberVO.Limit);
configurationBuilder.Properties<TelephoneVO>()
.HaveConversion<TelephoneConverter>()
.HaveMaxLength(TelephoneVO.Limit);
configurationBuilder.Properties<ModuleNameVO>()
.HaveConversion<ModuleNameConverter>();
}
}
@@ -0,0 +1,9 @@
namespace Vizhvizh.GoldGallery.Infrastructure.Exceptions;
public class EntityNotFoundException : Exception
{
public EntityNotFoundException() : base("not found entity")
{
}
}
@@ -0,0 +1,102 @@
using Vizhvizh.GoldGallery.Application;
using Vizhvizh.GoldGallery.Infrastructure.Configuration;
using Vizhvizh.GoldGallery.Infrastructure.EF;
using Vizhvizh.BuildingBlocks.Application.Configuration.Commnad;
using Vizhvizh.BuildingBlocks.Application.Configuration.Query;
using Vizhvizh.BuildingBlocks.Application.Data;
using Vizhvizh.BuildingBlocks.Application.Events;
using Vizhvizh.BuildingBlocks.Application.Outbox;
using Vizhvizh.BuildingBlocks.Infrastructure;
using Vizhvizh.BuildingBlocks.Infrastructure.DomainEventsDispatching;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.EntityFrameworkCore;
using Vizhvizh.GoldGallery.Domain.Shops.Repositories;
using Vizhvizh.GoldGallery.Infrastructure.Repositories;
using Vizhvizh.BuildingBlocks.Infrastructure.SelectBuilders;
using Vizhvizh.BuildingBlocks.Application.SelectBuilders;
using Vizhvizh.GoldGallery.Domain.Sliders.Repositories;
using Vizhvizh.BuildingBlocks.Infrastructure.Lifetimes;
using Vizhvizh.BuildingBlocks.Application.Validations;
using FluentValidation;
namespace Vizhvizh.GoldGallery.Infrastructure;
public class GoldGalleryStartup
{
public static void Initialize(IServiceCollection services, string connectionString)
{
services.AddDbContext<GoldGalleryDbContext>(op =>
{
op.UseSqlServer(connectionString);
});
services.AddScoped<DbContext>(sp => sp.GetRequiredService<GoldGalleryDbContext>());
services.AddScoped<IGoldGalleryModule, GoldGalleryModule>();
services.AddScoped<IUnitOfWork, UnitOfWork>();
services.AddScoped<IDomainEventsAccessor, DomainEventsAccessor>();
services.AddScoped<IDomainEventsDispatcher, DomainEventsDispatcher>();
services.AddScoped<IDomainNotificationsMapper, DomainNotificationsMapper>();
services.AddScoped<IExecutor, Executor>();
services.Scan(scan => scan.
FromAssemblies(Assemblies.Application, Assemblies.Infrastructure)
.AddClasses(classes => classes.AssignableTo(typeof(ICommandHandler<>)), publicOnly: false)
.AsImplementedInterfaces()
.WithScopedLifetime()
.AddClasses(classes => classes.AssignableTo(typeof(ICommandHandler<,>)), publicOnly: false)
.AsImplementedInterfaces()
.WithScopedLifetime()
.AddClasses(classes => classes.AssignableTo(typeof(IQueryHandler<,>)), publicOnly: false)
.AsImplementedInterfaces()
.WithScopedLifetime()
.AddClasses(classes => classes.AssignableTo(typeof(ICommandHandler<>)), publicOnly: false)
.AsImplementedInterfaces()
.WithScopedLifetime()
.AddClasses(classes => classes.AssignableTo(typeof(ISingletonDependency)), publicOnly: false)
.AsImplementedInterfaces()
.WithSingletonLifetime()
.AddClasses(classes => classes.AssignableTo(typeof(IScopeDependency)), publicOnly: false)
.AsImplementedInterfaces()
.WithScopedLifetime()
.AddClasses(classes => classes.AssignableTo(typeof(ITransientDependency)), publicOnly: false)
.AsImplementedInterfaces()
.WithTransientLifetime()
.AddClasses(classes => classes.AssignableTo(typeof(IValidator<>)), publicOnly: false)
.AsImplementedInterfaces()
.WithScopedLifetime()
);
services.Decorate(typeof(ICommandHandler<>), typeof(ValidationCommandHandlerDecorator<>));
services.Decorate(typeof(ICommandHandler<>), typeof(UnitOfWorkCommandHandlerDecorator<>));
services.Decorate(typeof(ICommandHandler<,>), typeof(ValidationCommandHandlerDecorator<,>));
services.Decorate(typeof(ICommandHandler<,>), typeof(UnitOfWorkCommandHandlerDecorator<,>));
services.AddScoped(sa =>
{
var notifications = sa.GetServices<IDomainEventNotification>();
var notificationDic = new BiDictionary<string, Type>();
foreach (var notification in notifications)
notificationDic.Add(notification!.ToString()!, notification!.GetType());
return notificationDic;
});
services.AddScoped<IOutbox>(sa =>
{
return null; // ToDo
});
services.AddScoped<ISqlConnectionFactory>(sp =>
{
return new SqlConnectionFactory(connectionString);
});
services.AddScoped<ISqlDialect, SqlServerDialect>();
services.AddScoped<ISqlSelectBuilder, SqlSelectBuilder>();
}
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,565 @@
using System;
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace Vizhvizh.GoldGallery.Infrastructure.Migrations
{
/// <inheritdoc />
public partial class initial : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.EnsureSchema(
name: "GoldGallery");
migrationBuilder.CreateSequence(
name: "Sequence_Categories",
schema: "GoldGallery");
migrationBuilder.CreateSequence(
name: "Sequence_Managements",
schema: "GoldGallery");
migrationBuilder.CreateSequence(
name: "Sequence_Members",
schema: "GoldGallery");
migrationBuilder.CreateSequence(
name: "Sequence_Products",
schema: "GoldGallery");
migrationBuilder.CreateSequence(
name: "Sequence_ProductSpecifications",
schema: "GoldGallery");
migrationBuilder.CreateSequence(
name: "Sequence_ProductVariants",
schema: "GoldGallery");
migrationBuilder.CreateSequence(
name: "Sequence_Resources",
schema: "GoldGallery");
migrationBuilder.CreateSequence(
name: "Sequence_RoleResources",
schema: "GoldGallery");
migrationBuilder.CreateSequence<int>(
name: "Sequence_Roles",
schema: "GoldGallery");
migrationBuilder.CreateSequence<int>(
name: "Sequence_ShippingMethods",
schema: "GoldGallery");
migrationBuilder.CreateSequence(
name: "Sequence_Shops",
schema: "GoldGallery");
migrationBuilder.CreateSequence(
name: "Sequence_Sliders",
schema: "GoldGallery");
migrationBuilder.CreateSequence(
name: "Sequence_Users",
schema: "GoldGallery");
migrationBuilder.CreateTable(
name: "Categories",
schema: "GoldGallery",
columns: table => new
{
Id = table.Column<long>(type: "bigint", nullable: false)
.Annotation("SqlServer:Identity", "1, 1"),
Title = table.Column<string>(type: "nvarchar(60)", maxLength: 60, nullable: false),
Description = table.Column<string>(type: "nvarchar(500)", maxLength: 500, nullable: true),
Image = table.Column<string>(type: "nvarchar(150)", maxLength: 150, nullable: false),
ParentId = table.Column<long>(type: "bigint", nullable: true),
Path = table.Column<string>(type: "HIERARCHYID", nullable: false),
RowVersion = table.Column<byte[]>(type: "rowversion", rowVersion: true, nullable: false),
CreateOn = table.Column<DateTime>(type: "datetime2", nullable: false, defaultValueSql: "GETDATE()")
},
constraints: table =>
{
table.PrimaryKey("PK_Categories", x => x.Id);
table.ForeignKey(
name: "FK_Categories_ParentId",
column: x => x.ParentId,
principalSchema: "GoldGallery",
principalTable: "Categories",
principalColumn: "Id",
onDelete: ReferentialAction.Restrict);
});
migrationBuilder.CreateTable(
name: "Resources",
schema: "GoldGallery",
columns: table => new
{
Id = table.Column<long>(type: "bigint", nullable: false)
.Annotation("SqlServer:Identity", "1, 1"),
Title = table.Column<string>(type: "nvarchar(60)", maxLength: 60, nullable: false),
Description = table.Column<string>(type: "nvarchar(500)", maxLength: 500, nullable: false),
ModuleName = table.Column<int>(type: "int", nullable: false),
ResourceKey = table.Column<string>(type: "nvarchar(max)", nullable: false),
RowVersion = table.Column<byte[]>(type: "rowversion", rowVersion: true, nullable: false),
CreateOn = table.Column<DateTime>(type: "datetime2", nullable: false, defaultValueSql: "GETDATE()")
},
constraints: table =>
{
table.PrimaryKey("PK_Resources", x => x.Id);
});
migrationBuilder.CreateTable(
name: "Shops",
schema: "GoldGallery",
columns: table => new
{
Id = table.Column<long>(type: "bigint", nullable: false)
.Annotation("SqlServer:Identity", "1, 1"),
OwnerId = table.Column<long>(type: "bigint", nullable: false),
Title = table.Column<string>(type: "nvarchar(60)", maxLength: 60, nullable: false),
Description = table.Column<string>(type: "nvarchar(500)", maxLength: 500, nullable: true),
Email = table.Column<string>(type: "nvarchar(200)", maxLength: 200, nullable: true),
Telephone = table.Column<string>(type: "nvarchar(11)", maxLength: 11, nullable: false),
Logo = table.Column<string>(type: "nvarchar(150)", maxLength: 150, nullable: true),
ShopBusinessLicenseImage = table.Column<string>(type: "nvarchar(150)", maxLength: 150, nullable: false),
ShopBusinessLicenseCode = table.Column<string>(type: "nvarchar(50)", maxLength: 50, nullable: false),
RowVersion = table.Column<byte[]>(type: "rowversion", rowVersion: true, nullable: false),
CreateOn = table.Column<DateTime>(type: "datetime2", nullable: false, defaultValueSql: "GETDATE()"),
Location = table.Column<string>(type: "nvarchar(max)", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_Shops", x => x.Id);
});
migrationBuilder.CreateTable(
name: "Sliders",
schema: "GoldGallery",
columns: table => new
{
Id = table.Column<long>(type: "bigint", nullable: false)
.Annotation("SqlServer:Identity", "1, 1"),
Title = table.Column<string>(type: "nvarchar(60)", maxLength: 60, nullable: false),
Image = table.Column<string>(type: "nvarchar(150)", maxLength: 150, nullable: false),
Url = table.Column<string>(type: "nvarchar(150)", maxLength: 150, nullable: false),
Type = table.Column<int>(type: "INT", nullable: false),
Key = table.Column<string>(type: "nvarchar(150)", maxLength: 150, nullable: false),
RowVersion = table.Column<byte[]>(type: "rowversion", rowVersion: true, nullable: false),
CreateOn = table.Column<DateTime>(type: "datetime2", nullable: false, defaultValueSql: "GETDATE()")
},
constraints: table =>
{
table.PrimaryKey("PK_Sliders", x => x.Id);
});
migrationBuilder.CreateTable(
name: "Users",
schema: "GoldGallery",
columns: table => new
{
Id = table.Column<long>(type: "bigint", nullable: false)
.Annotation("SqlServer:Identity", "1, 1"),
MemberId = table.Column<long>(type: "bigint", nullable: false),
RowVersion = table.Column<byte[]>(type: "rowversion", rowVersion: true, nullable: false),
CreateOn = table.Column<DateTime>(type: "datetime2", nullable: false, defaultValueSql: "GETDATE()")
},
constraints: table =>
{
table.PrimaryKey("PK_Users", x => x.Id);
});
migrationBuilder.CreateTable(
name: "Managements",
schema: "GoldGallery",
columns: table => new
{
Id = table.Column<long>(type: "bigint", nullable: false),
RowVersion = table.Column<byte[]>(type: "rowversion", rowVersion: true, nullable: false),
CreateOn = table.Column<DateTime>(type: "datetime2", nullable: false, defaultValueSql: "GETDATE()")
},
constraints: table =>
{
table.PrimaryKey("PK_Managements", x => x.Id);
table.ForeignKey(
name: "FK_Managements_Shops_Id",
column: x => x.Id,
principalSchema: "GoldGallery",
principalTable: "Shops",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateTable(
name: "Members",
schema: "GoldGallery",
columns: table => new
{
Id = table.Column<long>(type: "bigint", nullable: false)
.Annotation("SqlServer:Identity", "1, 1"),
FirstName = table.Column<string>(type: "nvarchar(50)", maxLength: 50, nullable: true),
LastName = table.Column<string>(type: "nvarchar(50)", maxLength: 50, nullable: true),
PhoneNumber = table.Column<string>(type: "nvarchar(11)", maxLength: 11, nullable: false),
Avatar = table.Column<string>(type: "nvarchar(150)", maxLength: 150, nullable: true),
NationalCode = table.Column<string>(type: "nvarchar(10)", maxLength: 10, nullable: true),
ShopId = table.Column<long>(type: "bigint", nullable: true),
RowVersion = table.Column<byte[]>(type: "rowversion", rowVersion: true, nullable: false),
CreateOn = table.Column<DateTime>(type: "datetime2", nullable: false, defaultValueSql: "GETDATE()")
},
constraints: table =>
{
table.PrimaryKey("PK_Members", x => x.Id);
table.ForeignKey(
name: "FK_Members_Shops_ShopId",
column: x => x.ShopId,
principalSchema: "GoldGallery",
principalTable: "Shops",
principalColumn: "Id");
});
migrationBuilder.CreateTable(
name: "Products",
schema: "GoldGallery",
columns: table => new
{
Id = table.Column<long>(type: "bigint", nullable: false)
.Annotation("SqlServer:Identity", "1, 1"),
ProductCondition = table.Column<int>(type: "int", nullable: false),
Title = table.Column<string>(type: "nvarchar(60)", maxLength: 60, nullable: false),
Description = table.Column<string>(type: "nvarchar(500)", maxLength: 500, nullable: false),
Score_Score = table.Column<byte>(type: "TINYINT", nullable: false, defaultValue: (byte)0),
TotalVoters = table.Column<int>(type: "INT", nullable: false, defaultValue: 0),
Image = table.Column<string>(type: "nvarchar(150)", maxLength: 150, nullable: false),
File3D = table.Column<string>(type: "nvarchar(150)", maxLength: 150, nullable: true),
CraftsmanshipFee = table.Column<decimal>(type: "decimal(4,2)", nullable: false),
CategoryId = table.Column<long>(type: "bigint", nullable: true),
ShopId = table.Column<long>(type: "bigint", nullable: true),
RowVersion = table.Column<byte[]>(type: "rowversion", rowVersion: true, nullable: false),
CreateOn = table.Column<DateTime>(type: "datetime2", nullable: false, defaultValueSql: "GETDATE()")
},
constraints: table =>
{
table.PrimaryKey("PK_Products", x => x.Id);
table.ForeignKey(
name: "FK_Products_Categories_CategoryId",
column: x => x.CategoryId,
principalSchema: "GoldGallery",
principalTable: "Categories",
principalColumn: "Id");
table.ForeignKey(
name: "FK_Products_Shops_ShopId",
column: x => x.ShopId,
principalSchema: "GoldGallery",
principalTable: "Shops",
principalColumn: "Id");
});
migrationBuilder.CreateTable(
name: "ShippingMethods",
schema: "GoldGallery",
columns: table => new
{
Id = table.Column<int>(type: "int", nullable: false)
.Annotation("SqlServer:Identity", "1, 1"),
Title = table.Column<string>(type: "nvarchar(60)", maxLength: 60, nullable: false),
Description = table.Column<string>(type: "nvarchar(500)", maxLength: 500, nullable: false),
Image = table.Column<string>(type: "nvarchar(150)", maxLength: 150, nullable: false),
ShopId = table.Column<long>(type: "bigint", nullable: true),
RowVersion = table.Column<byte[]>(type: "rowversion", rowVersion: true, nullable: false),
CreateOn = table.Column<DateTime>(type: "datetime2", nullable: false, defaultValueSql: "GETDATE()")
},
constraints: table =>
{
table.PrimaryKey("PK_ShippingMethods", x => x.Id);
table.ForeignKey(
name: "FK_ShippingMethods_Shops_ShopId",
column: x => x.ShopId,
principalSchema: "GoldGallery",
principalTable: "Shops",
principalColumn: "Id");
});
migrationBuilder.CreateTable(
name: "Roles",
schema: "GoldGallery",
columns: table => new
{
Id = table.Column<int>(type: "int", nullable: false)
.Annotation("SqlServer:Identity", "1, 1"),
Title = table.Column<string>(type: "nvarchar(60)", maxLength: 60, nullable: false),
ResourceId = table.Column<long>(type: "bigint", nullable: true),
UserId = table.Column<long>(type: "bigint", nullable: true),
RowVersion = table.Column<byte[]>(type: "rowversion", rowVersion: true, nullable: false),
CreateOn = table.Column<DateTime>(type: "datetime2", nullable: false, defaultValueSql: "GETDATE()")
},
constraints: table =>
{
table.PrimaryKey("PK_Roles", x => x.Id);
table.ForeignKey(
name: "FK_Roles_Resources_ResourceId",
column: x => x.ResourceId,
principalSchema: "GoldGallery",
principalTable: "Resources",
principalColumn: "Id");
table.ForeignKey(
name: "FK_Roles_Users_UserId",
column: x => x.UserId,
principalSchema: "GoldGallery",
principalTable: "Users",
principalColumn: "Id");
});
migrationBuilder.CreateTable(
name: "ProductSpecifications",
schema: "GoldGallery",
columns: table => new
{
Id = table.Column<long>(type: "bigint", nullable: false)
.Annotation("SqlServer:Identity", "1, 1"),
Title = table.Column<string>(type: "nvarchar(60)", maxLength: 60, nullable: false),
ItemValues = table.Column<string>(type: "nvarchar(max)", nullable: false),
ProductId = table.Column<long>(type: "bigint", nullable: true),
RowVersion = table.Column<byte[]>(type: "rowversion", rowVersion: true, nullable: false),
CreateOn = table.Column<DateTime>(type: "datetime2", nullable: false, defaultValueSql: "GETDATE()")
},
constraints: table =>
{
table.PrimaryKey("PK_ProductSpecifications", x => x.Id);
table.ForeignKey(
name: "FK_ProductSpecifications_Products_ProductId",
column: x => x.ProductId,
principalSchema: "GoldGallery",
principalTable: "Products",
principalColumn: "Id");
});
migrationBuilder.CreateTable(
name: "ProductVariants",
schema: "GoldGallery",
columns: table => new
{
Id = table.Column<long>(type: "bigint", nullable: false)
.Annotation("SqlServer:Identity", "1, 1"),
Score = table.Column<byte>(type: "TINYINT", nullable: false, defaultValue: (byte)0),
TotalVoters = table.Column<int>(type: "INT", nullable: false, defaultValue: 0),
Quantity = table.Column<double>(type: "float", nullable: false),
Weight = table.Column<decimal>(type: "decimal(7,3)", nullable: false),
ProductId = table.Column<long>(type: "bigint", nullable: true),
RowVersion = table.Column<byte[]>(type: "rowversion", rowVersion: true, nullable: false),
CreateOn = table.Column<DateTime>(type: "datetime2", nullable: false, defaultValueSql: "GETDATE()"),
Gallery = table.Column<string>(type: "nvarchar(max)", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_ProductVariants", x => x.Id);
table.ForeignKey(
name: "FK_ProductVariants_Products_ProductId",
column: x => x.ProductId,
principalSchema: "GoldGallery",
principalTable: "Products",
principalColumn: "Id");
});
migrationBuilder.CreateTable(
name: "RoleResources",
schema: "GoldGallery",
columns: table => new
{
Id = table.Column<long>(type: "bigint", nullable: false)
.Annotation("SqlServer:Identity", "1, 1"),
AccessLevel = table.Column<int>(type: "int", nullable: false),
RoleId = table.Column<int>(type: "int", nullable: true),
RowVersion = table.Column<byte[]>(type: "rowversion", rowVersion: true, nullable: false),
CreateOn = table.Column<DateTime>(type: "datetime2", nullable: false, defaultValueSql: "GETDATE()")
},
constraints: table =>
{
table.PrimaryKey("PK_RoleResources", x => x.Id);
table.ForeignKey(
name: "FK_RoleResources_Roles_RoleId",
column: x => x.RoleId,
principalSchema: "GoldGallery",
principalTable: "Roles",
principalColumn: "Id");
});
migrationBuilder.CreateIndex(
name: "IX_Categories_ParentId",
schema: "GoldGallery",
table: "Categories",
column: "ParentId");
migrationBuilder.CreateIndex(
name: "IX_Categories_Path",
schema: "GoldGallery",
table: "Categories",
column: "Path")
.Annotation("SqlServer:Clustered", false);
migrationBuilder.CreateIndex(
name: "IX_Members_ShopId",
schema: "GoldGallery",
table: "Members",
column: "ShopId");
migrationBuilder.CreateIndex(
name: "IX_Products_CategoryId",
schema: "GoldGallery",
table: "Products",
column: "CategoryId");
migrationBuilder.CreateIndex(
name: "IX_Products_ShopId",
schema: "GoldGallery",
table: "Products",
column: "ShopId");
migrationBuilder.CreateIndex(
name: "IX_ProductSpecifications_ProductId",
schema: "GoldGallery",
table: "ProductSpecifications",
column: "ProductId");
migrationBuilder.CreateIndex(
name: "IX_ProductVariants_ProductId",
schema: "GoldGallery",
table: "ProductVariants",
column: "ProductId");
migrationBuilder.CreateIndex(
name: "IX_RoleResources_RoleId",
schema: "GoldGallery",
table: "RoleResources",
column: "RoleId");
migrationBuilder.CreateIndex(
name: "IX_Roles_ResourceId",
schema: "GoldGallery",
table: "Roles",
column: "ResourceId");
migrationBuilder.CreateIndex(
name: "IX_Roles_UserId",
schema: "GoldGallery",
table: "Roles",
column: "UserId");
migrationBuilder.CreateIndex(
name: "IX_ShippingMethods_ShopId",
schema: "GoldGallery",
table: "ShippingMethods",
column: "ShopId");
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "Managements",
schema: "GoldGallery");
migrationBuilder.DropTable(
name: "Members",
schema: "GoldGallery");
migrationBuilder.DropTable(
name: "ProductSpecifications",
schema: "GoldGallery");
migrationBuilder.DropTable(
name: "ProductVariants",
schema: "GoldGallery");
migrationBuilder.DropTable(
name: "RoleResources",
schema: "GoldGallery");
migrationBuilder.DropTable(
name: "ShippingMethods",
schema: "GoldGallery");
migrationBuilder.DropTable(
name: "Sliders",
schema: "GoldGallery");
migrationBuilder.DropTable(
name: "Products",
schema: "GoldGallery");
migrationBuilder.DropTable(
name: "Roles",
schema: "GoldGallery");
migrationBuilder.DropTable(
name: "Categories",
schema: "GoldGallery");
migrationBuilder.DropTable(
name: "Shops",
schema: "GoldGallery");
migrationBuilder.DropTable(
name: "Resources",
schema: "GoldGallery");
migrationBuilder.DropTable(
name: "Users",
schema: "GoldGallery");
migrationBuilder.DropSequence(
name: "Sequence_Categories",
schema: "GoldGallery");
migrationBuilder.DropSequence(
name: "Sequence_Managements",
schema: "GoldGallery");
migrationBuilder.DropSequence(
name: "Sequence_Members",
schema: "GoldGallery");
migrationBuilder.DropSequence(
name: "Sequence_Products",
schema: "GoldGallery");
migrationBuilder.DropSequence(
name: "Sequence_ProductSpecifications",
schema: "GoldGallery");
migrationBuilder.DropSequence(
name: "Sequence_ProductVariants",
schema: "GoldGallery");
migrationBuilder.DropSequence(
name: "Sequence_Resources",
schema: "GoldGallery");
migrationBuilder.DropSequence(
name: "Sequence_RoleResources",
schema: "GoldGallery");
migrationBuilder.DropSequence(
name: "Sequence_Roles",
schema: "GoldGallery");
migrationBuilder.DropSequence(
name: "Sequence_ShippingMethods",
schema: "GoldGallery");
migrationBuilder.DropSequence(
name: "Sequence_Shops",
schema: "GoldGallery");
migrationBuilder.DropSequence(
name: "Sequence_Sliders",
schema: "GoldGallery");
migrationBuilder.DropSequence(
name: "Sequence_Users",
schema: "GoldGallery");
}
}
}
@@ -0,0 +1,12 @@
using Vizhvizh.BuildingBlocks.Domain;
using Vizhvizh.BuildingBlocks.Infrastructure.Lifetimes;
using Vizhvizh.GoldGallery.Domain.Products.Entities;
using Vizhvizh.GoldGallery.Domain.Products.Repositories;
using Vizhvizh.GoldGallery.Domain.Products.TypeIds;
using Vizhvizh.GoldGallery.Infrastructure.EF;
namespace Vizhvizh.GoldGallery.Infrastructure.Repositories;
internal class CategoryRepository(GoldGalleryDbContext context) : RepositoryBase<Category, CategoryId>(context), ICategoryRepository, IScopeDependency
{
}
@@ -0,0 +1,12 @@
using Vizhvizh.BuildingBlocks.Domain;
using Vizhvizh.BuildingBlocks.Infrastructure.Lifetimes;
using Vizhvizh.GoldGallery.Domain.Products.Entities;
using Vizhvizh.GoldGallery.Domain.Products.Repositories;
using Vizhvizh.GoldGallery.Domain.Products.TypeIds;
using Vizhvizh.GoldGallery.Infrastructure.EF;
namespace Vizhvizh.GoldGallery.Infrastructure.Repositories;
internal class ProductRepository(GoldGalleryDbContext context) : RepositoryBase<Product, ProductId>(context), IProductRepository, IScopeDependency
{
}
@@ -0,0 +1,12 @@
using Vizhvizh.BuildingBlocks.Infrastructure.Lifetimes;
using Vizhvizh.GoldGallery.Domain.Shops.Entities;
using Vizhvizh.GoldGallery.Domain.Shops.Repositories;
using Vizhvizh.GoldGallery.Domain.Shops.TypeIds;
using Vizhvizh.GoldGallery.Infrastructure.EF;
namespace Vizhvizh.GoldGallery.Infrastructure.Repositories
{
internal class ShopRepository(GoldGalleryDbContext context) : RepositoryBase<Shop, ShopId>(context), IShopRepository, IScopeDependency
{
}
}
@@ -0,0 +1,11 @@
using Vizhvizh.BuildingBlocks.Infrastructure.Lifetimes;
using Vizhvizh.GoldGallery.Domain.Sliders.Entities;
using Vizhvizh.GoldGallery.Domain.Sliders.Repositories;
using Vizhvizh.GoldGallery.Domain.Sliders.TypeIds;
using Vizhvizh.GoldGallery.Infrastructure.EF;
namespace Vizhvizh.GoldGallery.Infrastructure.Repositories;
internal class SliderRepository(GoldGalleryDbContext context) : RepositoryBase<Slider, SliderId>(context), ISliderRepository, IScopeDependency
{
}
@@ -0,0 +1,53 @@
using Microsoft.EntityFrameworkCore;
using Vizhvizh.BuildingBlocks.Domain;
using Vizhvizh.GoldGallery.Infrastructure.EF;
using Vizhvizh.GoldGallery.Infrastructure.Exceptions;
namespace Vizhvizh.GoldGallery.Infrastructure;
internal class RepositoryBase<T, TId> : IRepositoryBase<T, TId>
where T : Entity<TId> where TId : ITypeIdValueBase
{
private readonly GoldGalleryDbContext _goldGalleryDbContext;
public RepositoryBase(GoldGalleryDbContext goldGalleryDbContext)
{
this._goldGalleryDbContext = goldGalleryDbContext;
}
public async Task AddAsync(T entity, CancellationToken cancellationToken)
{
await _goldGalleryDbContext.AddAsync(entity, cancellationToken);
}
public async Task DeleteAsync(TId id, CancellationToken cancellationToken)
{
var entity = await FindByIdAsync(id, cancellationToken);
if (entity == null)
throw new EntityNotFoundException();
_goldGalleryDbContext.Remove(entity);
}
public Task DeleteAsync(T entity, CancellationToken cancellationToken)
{
_goldGalleryDbContext.Remove(entity);
return Task.CompletedTask;
}
public async Task<T?> FindByIdAsync(TId id, CancellationToken cancellationToken)
{
var entity = _goldGalleryDbContext.Set<T>();
return await entity.FindAsync(id, cancellationToken);
}
public IQueryable<T> GetQueryAsNoTracking()
=> _goldGalleryDbContext.Set<T>().AsNoTracking();
public Task UpdateAsync(T entity, CancellationToken cancellationToken)
{
_goldGalleryDbContext.Update(entity);
return Task.CompletedTask;
}
}
@@ -0,0 +1,23 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="8.0.25">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="8.0.25">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Vichvich.Shared.Infrastructure\Vizhvizh.Shared.Infrastructure.csproj" />
<ProjectReference Include="..\Vizhvizh.GoldGallery.Application\Vizhvizh.GoldGallery.Application.csproj" />
</ItemGroup>
</Project>