بلاخره تموم شد
This commit is contained in:
@@ -5,6 +5,7 @@ using System.Reflection;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using VizhTalk.Learning.Application;
|
||||
using VizhTalk.Learning.Domain.Entities;
|
||||
|
||||
namespace VizhTalk.Learning.Infrastructure.Configuration
|
||||
{
|
||||
@@ -12,5 +13,6 @@ namespace VizhTalk.Learning.Infrastructure.Configuration
|
||||
{
|
||||
public static Assembly Infrastructure = typeof(LearningStartup).Assembly;
|
||||
public static Assembly Application = typeof(ILearningModule).Assembly;
|
||||
public static Assembly Domain = typeof(Language).Assembly;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +1,14 @@
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using System;
|
||||
using System.Data;
|
||||
using VizhTalk.BuildingBlocks.Application.Configuration.Commnad;
|
||||
using VizhTalk.BuildingBlocks.Application.Configuration.Query;
|
||||
using VizhTalk.BuildingBlocks.Application.Contract;
|
||||
using VizhTalk.BuildingBlocks.Domain;
|
||||
using VizhTalk.BuildingBlocks.Domain.Contract;
|
||||
using VizhTalk.BuildingBlocks.Infrastructure;
|
||||
using VizhTalk.Learning.Application;
|
||||
using static Microsoft.EntityFrameworkCore.DbLoggerCategory.Database;
|
||||
|
||||
namespace VizhTalk.Learning.Infrastructure.Configuration;
|
||||
|
||||
@@ -21,19 +25,34 @@ public class LearningModule(IServiceProvider serviceProvider) : ILearningModule
|
||||
|
||||
public async Task<TResult> Execute<TResult>(ICommand<TResult> command, CancellationToken cancellationToken = default)
|
||||
{
|
||||
var handlerType = typeof(ICommandHandler<,>).MakeGenericType(command.GetType());
|
||||
|
||||
var commandType = command.GetType(); // مثلا CreateUserCommand
|
||||
var resultType = commandType.GetInterface(typeof(ICommand<>).Name)!.GetGenericArguments()[0];
|
||||
|
||||
// حالا handlerType میشه:
|
||||
var handlerType = typeof(ICommandHandler<,>).MakeGenericType(commandType, resultType);
|
||||
|
||||
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 = default)
|
||||
{
|
||||
var handlerType = typeof(ICommandHandler<,>).MakeGenericType(query.GetType());
|
||||
var queryType = query.GetType();
|
||||
var resultType = queryType.GetInterface(typeof(IQuery<>).Name)!.GetGenericArguments()[0];
|
||||
|
||||
// حالا handlerType میشه:
|
||||
var handlerType = typeof(IQueryHandler<,>).MakeGenericType(queryType, resultType);
|
||||
|
||||
var handler = serviceProvider.GetRequiredService(handlerType);
|
||||
|
||||
dynamic dynamicHandler = handler;
|
||||
dynamic dynamicQuery = query;
|
||||
|
||||
return await dynamicHandler.Handle(dynamicQuery, cancellationToken);
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Metadata.Builders;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using VizhTalk.Learning.Domain.Entities;
|
||||
|
||||
namespace VizhTalk.Learning.Infrastructure.EF.Configurations
|
||||
{
|
||||
internal class LanguageConfiguration : IEntityTypeConfiguration<Language>
|
||||
{
|
||||
public void Configure(EntityTypeBuilder<Language> builder)
|
||||
{
|
||||
builder.ToTable(nameof(Language), Schema.Learning);
|
||||
builder.HasKey(x => x.Id);
|
||||
|
||||
builder.Property(x => x.Id)
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasConversion(x => x.Value, x => new Domain.TypeIds.LanguageId(x));
|
||||
|
||||
builder.Property(x => x.Title)
|
||||
.HasConversion(s => s.Value, s => new Domain.ValueObjects.LanguageTitle(s))
|
||||
.HasMaxLength(60);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,15 +1,26 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||
using VizhTalk.BuildingBlocks.Domain;
|
||||
using VizhTalk.BuildingBlocks.Infrastructure.EF.Helpers;
|
||||
using VizhTalk.Learning.Infrastructure.Configuration;
|
||||
|
||||
namespace VizhTalk.Learning.Infrastructure.EF;
|
||||
|
||||
public class LearningDbContext : DbContext
|
||||
{
|
||||
public LearningDbContext(DbContextOptions<LearningDbContext> options)
|
||||
: base(options)
|
||||
{
|
||||
|
||||
}
|
||||
protected override void OnModelCreating(ModelBuilder modelBuilder)
|
||||
{
|
||||
base.OnModelCreating(modelBuilder);
|
||||
|
||||
modelBuilder.FindEntities()
|
||||
modelBuilder.HasDefaultSchema(Schema.Learning);
|
||||
|
||||
modelBuilder.FindEntities(Assemblies.Domain)
|
||||
.ApplyConfigurationsFromAssembly(Assemblies.Infrastructure, x => x.FullName.Contains("EF.Configurations"))
|
||||
.PluralizeEntities();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace VizhTalk.Learning.Infrastructure.EF
|
||||
{
|
||||
public class Schema
|
||||
{
|
||||
public const string Learning = "Learning";
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,14 +1,19 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using VizhTalk.BuildingBlocks.Application;
|
||||
using VizhTalk.BuildingBlocks.Application.Configuration.Commnad;
|
||||
using VizhTalk.BuildingBlocks.Application.Configuration.Query;
|
||||
using VizhTalk.BuildingBlocks.Application.Data;
|
||||
using VizhTalk.BuildingBlocks.Application.Events;
|
||||
using VizhTalk.BuildingBlocks.Application.Outbox;
|
||||
using VizhTalk.BuildingBlocks.Infrastructure;
|
||||
using VizhTalk.BuildingBlocks.Infrastructure.DomainEventsDispatching;
|
||||
using VizhTalk.Learning.Application;
|
||||
using VizhTalk.Learning.Application.Mappers;
|
||||
using VizhTalk.Learning.Infrastructure.Configuration;
|
||||
using VizhTalk.Learning.Infrastructure.EF;
|
||||
using VizhTalk.Learning.Infrastructure.Outbox;
|
||||
|
||||
namespace VizhTalk.Learning.Infrastructure;
|
||||
|
||||
@@ -16,16 +21,21 @@ public static class LearningStartup
|
||||
{
|
||||
public static void Initialize(this IServiceCollection services, string connectionString)
|
||||
{
|
||||
var domainNotificationsMap = new BiDictionary<string, Type>();
|
||||
|
||||
services.AddDbContext<LearningDbContext>(op =>
|
||||
{
|
||||
op.UseSqlServer(connectionString);
|
||||
});
|
||||
services.AddScoped<DbContext, LearningDbContext>();
|
||||
services.AddScoped<ILearningModule, LearningModule>();
|
||||
services.AddScoped<IExecutor, LearningModule>();
|
||||
services.AddScoped<IUnitOfWorkBase, UnitOfWorkBase>();
|
||||
services.AddScoped<IUnitOfWork, UnitOfWork>();
|
||||
services.AddScoped<IDomainEventsAccessor, DomainEventsAccessor>();
|
||||
services.AddScoped<IDomainEventsDispatcher, DomainEventsDispatcher>();
|
||||
services.AddScoped<IDomainNotificationsMapper, DomainNotificationsMapper>();
|
||||
services.AddScoped(sp => domainNotificationsMap);
|
||||
services.Scan(scan => scan.
|
||||
FromAssemblies(Assemblies.Application, Assemblies.Infrastructure)
|
||||
.AddClasses(classes => classes.AssignableTo(typeof(ICommandHandler<>)), publicOnly: false)
|
||||
@@ -40,7 +50,11 @@ public static class LearningStartup
|
||||
.AddClasses(classes => classes.AssignableTo(typeof(ICommandHandler<>)), publicOnly: false)
|
||||
.AsImplementedInterfaces()
|
||||
.WithScopedLifetime());
|
||||
services.Decorate(typeof(ICommandHandler<,>), typeof(UnitOfWorkCommandHandlerDecorator<,>));
|
||||
services.Decorate(typeof(ICommandHandler<>), typeof(UnitOfWorkCommandHandlerDecorator<>));
|
||||
|
||||
MapperConfig.Process();
|
||||
|
||||
services.AddScoped(sa =>
|
||||
{
|
||||
var notifications = sa.GetServices<IDomainEventNotification>();
|
||||
@@ -52,9 +66,16 @@ public static class LearningStartup
|
||||
});
|
||||
services.AddScoped<IOutbox>(sa =>
|
||||
{
|
||||
return null; // ToDo
|
||||
return new OutboxAccessor(); // ToDo
|
||||
});
|
||||
|
||||
services.AddScoped<ISqlConnectionFactory>(x => new SqlConnectionFactory(connectionString));
|
||||
}
|
||||
|
||||
public static void UseLearningModule(this IApplicationBuilder app)
|
||||
{
|
||||
using var scope = app.ApplicationServices.CreateScope();
|
||||
var db = scope.ServiceProvider.GetRequiredService<LearningDbContext>();
|
||||
db.Database.Migrate();
|
||||
}
|
||||
}
|
||||
+54
@@ -0,0 +1,54 @@
|
||||
// <auto-generated />
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||
using Microsoft.EntityFrameworkCore.Metadata;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||
using VizhTalk.Learning.Infrastructure.EF;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace VizhTalk.Learning.Infrastructure.Migrations
|
||||
{
|
||||
[DbContext(typeof(LearningDbContext))]
|
||||
[Migration("20250901155327_Initial")]
|
||||
partial class Initial
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||
{
|
||||
#pragma warning disable 612, 618
|
||||
modelBuilder
|
||||
.HasDefaultSchema("Learning")
|
||||
.HasAnnotation("ProductVersion", "8.0.19")
|
||||
.HasAnnotation("Relational:MaxIdentifierLength", 128);
|
||||
|
||||
SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder);
|
||||
|
||||
modelBuilder.Entity("VizhTalk.Learning.Domain.Entities.Language", b =>
|
||||
{
|
||||
b.Property<long>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("bigint");
|
||||
|
||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<long>("Id"));
|
||||
|
||||
b.Property<bool>("IsActive")
|
||||
.HasColumnType("bit");
|
||||
|
||||
b.Property<bool>("IsDeleted")
|
||||
.HasColumnType("bit");
|
||||
|
||||
b.Property<string>("Title")
|
||||
.IsRequired()
|
||||
.HasMaxLength(60)
|
||||
.HasColumnType("nvarchar(60)");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("Languages", "Learning");
|
||||
});
|
||||
#pragma warning restore 612, 618
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace VizhTalk.Learning.Infrastructure.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class Initial : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.EnsureSchema(
|
||||
name: "Learning");
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "Languages",
|
||||
schema: "Learning",
|
||||
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),
|
||||
IsDeleted = table.Column<bool>(type: "bit", nullable: false),
|
||||
IsActive = table.Column<bool>(type: "bit", nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_Languages", x => x.Id);
|
||||
});
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropTable(
|
||||
name: "Languages",
|
||||
schema: "Learning");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
// <auto-generated />
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||
using Microsoft.EntityFrameworkCore.Metadata;
|
||||
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||
using VizhTalk.Learning.Infrastructure.EF;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace VizhTalk.Learning.Infrastructure.Migrations
|
||||
{
|
||||
[DbContext(typeof(LearningDbContext))]
|
||||
partial class LearningDbContextModelSnapshot : ModelSnapshot
|
||||
{
|
||||
protected override void BuildModel(ModelBuilder modelBuilder)
|
||||
{
|
||||
#pragma warning disable 612, 618
|
||||
modelBuilder
|
||||
.HasDefaultSchema("Learning")
|
||||
.HasAnnotation("ProductVersion", "8.0.19")
|
||||
.HasAnnotation("Relational:MaxIdentifierLength", 128);
|
||||
|
||||
SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder);
|
||||
|
||||
modelBuilder.Entity("VizhTalk.Learning.Domain.Entities.Language", b =>
|
||||
{
|
||||
b.Property<long>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("bigint");
|
||||
|
||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<long>("Id"));
|
||||
|
||||
b.Property<bool>("IsActive")
|
||||
.HasColumnType("bit");
|
||||
|
||||
b.Property<bool>("IsDeleted")
|
||||
.HasColumnType("bit");
|
||||
|
||||
b.Property<string>("Title")
|
||||
.IsRequired()
|
||||
.HasMaxLength(60)
|
||||
.HasColumnType("nvarchar(60)");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("Languages", "Learning");
|
||||
});
|
||||
#pragma warning restore 612, 618
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -15,12 +15,12 @@ namespace VizhTalk.Learning.Infrastructure.Outbox
|
||||
}
|
||||
public void Add(OutboxMessage message)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
|
||||
}
|
||||
|
||||
public Task Save()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
using VizhTalk.BuildingBlocks.Infrastructure;
|
||||
using VizhTalk.Learning.Domain.Entities;
|
||||
using VizhTalk.Learning.Domain.Repositories;
|
||||
using VizhTalk.Learning.Domain.TypeIds;
|
||||
using VizhTalk.Learning.Infrastructure.EF;
|
||||
|
||||
namespace VizhTalk.Learning.Infrastructure.Repositories
|
||||
{
|
||||
internal class LanguageRepository : RepositoryBase<Language, LanguageId>, ILanguageRepository
|
||||
{
|
||||
public LanguageRepository(LearningDbContext dbContext) : base(dbContext)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using VizhTalk.BuildingBlocks.Infrastructure;
|
||||
using VizhTalk.BuildingBlocks.Infrastructure.DomainEventsDispatching;
|
||||
using VizhTalk.Learning.Application;
|
||||
using VizhTalk.Learning.Domain.Repositories;
|
||||
using VizhTalk.Learning.Infrastructure.EF;
|
||||
using VizhTalk.Learning.Infrastructure.Repositories;
|
||||
|
||||
namespace VizhTalk.Learning.Infrastructure
|
||||
{
|
||||
internal class UnitOfWork(LearningDbContext learningDbContext, IDomainEventsDispatcher domainEventsDispatcher)
|
||||
: UnitOfWorkBase(learningDbContext, domainEventsDispatcher), IUnitOfWork
|
||||
{
|
||||
private ILanguageRepository _language;
|
||||
public ILanguageRepository Language
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_language == null)
|
||||
_language = new LanguageRepository(learningDbContext);
|
||||
|
||||
return _language;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6,6 +6,18 @@
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.AspNetCore.Http.Abstractions" Version="2.3.0" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="8.0.19">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="8.0.19">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\VizhTalk.BuildingBlocks.Infrastructure\VizhTalk.BuildingBlocks.Infrastructure.csproj" />
|
||||
<ProjectReference Include="..\VizhTalk.Learning.Application\VizhTalk.Learning.Application.csproj" />
|
||||
|
||||
Reference in New Issue
Block a user