Wizard Dosyalarından IMultiTenant özelliği kaldırıldı

This commit is contained in:
Sedat ÖZTÜRK 2026-09-01 11:28:52 +03:00
parent 7ec77c551f
commit c4de55d459
13 changed files with 76 additions and 166 deletions

View file

@ -32,11 +32,11 @@ public class DynamicAppServiceAppService : PlatformAppService, IDynamicServiceAp
{
try
{
return await _compiler.CompileAndValidateAsync(request.Code, CurrentTenant.Id);
return await _compiler.CompileAndValidateAsync(request.Code);
}
catch (Exception ex)
{
Logger.LogError(ex, "Failed to test compile dynamic service. Tenant: {TenantId}", CurrentTenant.Id);
Logger.LogError(ex, "Failed to test compile dynamic service");
throw;
}
}
@ -47,7 +47,7 @@ public class DynamicAppServiceAppService : PlatformAppService, IDynamicServiceAp
try
{
// Önce kodu test compile et
var compileResult = await _compiler.CompileAndValidateAsync(request.Code, CurrentTenant.Id);
var compileResult = await _compiler.CompileAndValidateAsync(request.Code);
if (!compileResult.Success)
{
return new PublishResultDto
@ -58,8 +58,7 @@ public class DynamicAppServiceAppService : PlatformAppService, IDynamicServiceAp
}
// Aynı isimde AppService var mı kontrol et
var existingService = await _dynamicAppServiceRepository
.FirstOrDefaultAsync(x => x.Name == request.Name && x.TenantId == CurrentTenant.Id);
var existingService = await _dynamicAppServiceRepository.FirstOrDefaultAsync(x => x.Name == request.Name);
DynamicService appService;
@ -79,8 +78,7 @@ public class DynamicAppServiceAppService : PlatformAppService, IDynamicServiceAp
appService = new DynamicService(
GuidGenerator.Create(),
request.Name,
request.Code,
CurrentTenant.Id)
request.Code)
{
DisplayName = request.DisplayName,
Description = request.Description,
@ -97,9 +95,7 @@ public class DynamicAppServiceAppService : PlatformAppService, IDynamicServiceAp
// Pasif olarak yayınlanıyorsa mevcut kaydı kaldır, assembly yükleme
if (!request.IsActive)
{
DynamicServiceCompiler.NotifyAssemblyUnregistration?.Invoke(
CurrentTenant.Id ?? Guid.Empty,
appService.Name);
DynamicServiceCompiler.NotifyAssemblyUnregistration?.Invoke(appService.Name);
appService.MarkCompilationSuccess();
await _dynamicAppServiceRepository.UpdateAsync(appService);
@ -113,8 +109,7 @@ public class DynamicAppServiceAppService : PlatformAppService, IDynamicServiceAp
};
}
var loadResult = await _compiler.CompileAndRegisterForTenantAsync(
CurrentTenant.Id ?? Guid.Empty,
var loadResult = await _compiler.CompileAndRegisterAsync(
request.Code,
assemblyName);
@ -152,8 +147,7 @@ public class DynamicAppServiceAppService : PlatformAppService, IDynamicServiceAp
}
catch (Exception ex)
{
Logger.LogError(ex, "Failed to publish dynamic service. Name: {Name}, Tenant: {TenantId}",
request.Name, CurrentTenant.Id);
Logger.LogError(ex, "Failed to publish dynamic service. Name: {Name}", request.Name);
return new PublishResultDto
{
@ -166,11 +160,8 @@ public class DynamicAppServiceAppService : PlatformAppService, IDynamicServiceAp
[Authorize(AppCodes.DeveloperKits.DynamicServices.DynamicService)]
public virtual async Task<PagedResultDto<DynamicServiceDto>> GetListAsync(PagedAndSortedResultRequestDto input)
{
Logger.LogDebug("AppService listesi istendi. Tenant: {TenantId}", CurrentTenant.Id);
var queryable = await _dynamicAppServiceRepository.GetQueryableAsync();
// Tenant filtresi otomatik uygulanır (IMultiTenant)
var query = queryable.WhereIf(!string.IsNullOrEmpty(input.Sorting),
x => x.CreationTime.ToString().Contains(input.Sorting ?? ""));
@ -200,9 +191,7 @@ public class DynamicAppServiceAppService : PlatformAppService, IDynamicServiceAp
var appService = await _dynamicAppServiceRepository.GetAsync(id);
// Runtime'dan assembly ve Swagger endpoint'ini kaldır
DynamicServiceCompiler.NotifyAssemblyUnregistration?.Invoke(
CurrentTenant.Id ?? Guid.Empty,
appService.Name);
DynamicServiceCompiler.NotifyAssemblyUnregistration?.Invoke(appService.Name);
await _dynamicAppServiceRepository.DeleteAsync(id);
}
@ -217,16 +206,13 @@ public class DynamicAppServiceAppService : PlatformAppService, IDynamicServiceAp
if (!isActive)
{
// Pasif yapılınca Swagger/MVC'den endpoint'i kaldır
DynamicServiceCompiler.NotifyAssemblyUnregistration?.Invoke(
CurrentTenant.Id ?? Guid.Empty,
appService.Name);
DynamicServiceCompiler.NotifyAssemblyUnregistration?.Invoke(appService.Name);
}
else if (appService.CompilationStatus == CompilationStatus.Success)
{
// Aktif yapılınca yeniden derle ve yayınla
var assemblyName = $"{appService.Name}_{appService.Version}";
var result = await _compiler.CompileAndRegisterForTenantAsync(
CurrentTenant.Id ?? Guid.Empty,
var result = await _compiler.CompileAndRegisterAsync(
appService.Code,
assemblyName);
@ -255,8 +241,7 @@ public class DynamicAppServiceAppService : PlatformAppService, IDynamicServiceAp
{
// Service.Name üzerinden assembly adı oluştur
var assemblyName = $"{service.Name}_{service.Version}";
var result = await _compiler.CompileAndRegisterForTenantAsync(
CurrentTenant.Id ?? Guid.Empty,
var result = await _compiler.CompileAndRegisterAsync(
service.Code,
assemblyName);
@ -288,8 +273,7 @@ public class DynamicAppServiceAppService : PlatformAppService, IDynamicServiceAp
var appService = await _dynamicAppServiceRepository.GetAsync(id);
var assemblyName = $"{appService.Name}_{appService.Version + 1}";
var result = await _compiler.CompileAndRegisterForTenantAsync(
CurrentTenant.Id ?? Guid.Empty,
var result = await _compiler.CompileAndRegisterAsync(
appService.Code,
assemblyName);

View file

@ -1,5 +1,4 @@
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
@ -22,23 +21,24 @@ public class DynamicServiceCompiler : ITransientDependency
{
private readonly ILogger<DynamicServiceCompiler> _logger;
// Tenant bazlı yüklenmiş assembly'leri takip etmek için
private static readonly ConcurrentDictionary<Guid, List<Assembly>> _tenantAssemblies = new();
// Yüklenmiş dinamik assembly'leri takip etmek için
private static readonly List<Assembly> _loadedAssemblies = new();
private static readonly object _loadedAssembliesLock = new();
// Assembly kaydı için delegate
public static Action<Guid, Assembly, string>? NotifyAssemblyRegistration { get; set; }
public static Action<Assembly, string>? NotifyAssemblyRegistration { get; set; }
// Assembly silinme bildirimi için delegate
public static Action<Guid, string>? NotifyAssemblyUnregistration { get; set; }
public static Action<string>? NotifyAssemblyUnregistration { get; set; }
/// <summary>
/// Belirtilen tenant ve assembly adı prefix'ine ait assembly'leri tenant cache'inden kaldırır.
/// Belirtilen assembly adı prefix'ine ait assembly'leri cache'ten kaldırır.
/// </summary>
public static void UnregisterTenantAssemblyByPrefix(Guid tenantId, string assemblyNamePrefix)
public static void UnregisterAssemblyByPrefix(string assemblyNamePrefix)
{
if (_tenantAssemblies.TryGetValue(tenantId, out var assemblies))
lock (_loadedAssembliesLock)
{
assemblies.RemoveAll(a => a.GetName().Name?.StartsWith(assemblyNamePrefix) == true);
_loadedAssemblies.RemoveAll(a => a.GetName().Name?.StartsWith(assemblyNamePrefix) == true);
}
}
@ -81,7 +81,7 @@ public class DynamicServiceCompiler : ITransientDependency
/// <summary>
/// Kodu derler ve validate eder, ancak assembly yüklemez
/// </summary>
public async Task<CompileResultDto> CompileAndValidateAsync(string code, Guid? tenantId = null)
public async Task<CompileResultDto> CompileAndValidateAsync(string code)
{
var stopwatch = Stopwatch.StartNew();
@ -160,14 +160,14 @@ public class DynamicServiceCompiler : ITransientDependency
}
/// <summary>
/// Kodu derler ve belirtilen tenant için assembly yükler
/// Kodu derler ve assembly'yi yükler
/// </summary>
public async Task<CompileResultDto> CompileAndRegisterForTenantAsync(Guid tenantId, string code, string assemblyName)
public async Task<CompileResultDto> CompileAndRegisterAsync(string code, string assemblyName)
{
try
{
// Önce validate et
var validateResult = await CompileAndValidateAsync(code, tenantId);
var validateResult = await CompileAndValidateAsync(code);
if (!validateResult.Success)
{
return validateResult;
@ -186,21 +186,17 @@ public class DynamicServiceCompiler : ITransientDependency
ms.Seek(0, SeekOrigin.Begin);
// Tenant'a özel assembly load context
var contextName = $"Tenant_{tenantId}_Context";
var loadContext = new AssemblyLoadContext(contextName, isCollectible: true);
// Her dinamik assembly kendi collectible context'inde yüklenir
var loadContext = new AssemblyLoadContext($"Dynamic_{assemblyName}_Context", isCollectible: true);
var assembly = loadContext.LoadFromStream(ms);
var appServiceTypes = assembly.GetTypes()
.Where(t => IsApplicationServiceType(t))
.ToList();
lock (_loadedAssembliesLock)
{
_loadedAssemblies.Add(assembly);
}
_tenantAssemblies.AddOrUpdate(tenantId,
new List<Assembly> { assembly },
(key, existing) => { existing.Add(assembly); return existing; });
NotifyAssemblyRegistration?.Invoke(tenantId, assembly, assemblyName);
NotifyAssemblyRegistration?.Invoke(assembly, assemblyName);
return new CompileResultDto
{
@ -211,7 +207,7 @@ public class DynamicServiceCompiler : ITransientDependency
}
catch (Exception ex)
{
_logger.LogError(ex, "Failed to load assembly. Tenant: {TenantId}", tenantId);
_logger.LogError(ex, "Failed to load assembly: {Assembly}", assemblyName);
return new CompileResultDto
{

View file

@ -6862,7 +6862,7 @@ public class ListFormSeeder_Saas : IDataSeedContributor, ITransientDependency
Name = listFormName,
Title = listFormName,
DataSourceCode = SeedConsts.DataSources.DefaultCode,
IsTenant = true,
IsTenant = false,
IsBranch = false,
IsOrganizationUnit = false,
Description = $"{listFormName}.Description",

View file

@ -1,13 +1,10 @@
using System;
using Volo.Abp.Domain.Entities.Auditing;
using Volo.Abp.MultiTenancy;
namespace Sozsoft.Platform.Entities;
public class CrudEndpoint : FullAuditedEntity<Guid>, IMultiTenant
public class CrudEndpoint : FullAuditedEntity<Guid>
{
public virtual Guid? TenantId { get; protected set; }
public string EntityName { get; set; } = string.Empty;
public string Method { get; set; } = string.Empty;
public string Path { get; set; } = string.Empty;

View file

@ -1,13 +1,10 @@
using System;
using Volo.Abp.Domain.Entities.Auditing;
using Volo.Abp.MultiTenancy;
namespace Sozsoft.Platform.Entities;
public class CustomComponent : FullAuditedEntity<Guid>, IMultiTenant
public class CustomComponent : FullAuditedEntity<Guid>
{
public virtual Guid? TenantId { get; protected set; }
public string Name { get; set; } = string.Empty;
public string RoutePath { get; set; } = string.Empty;
public string Code { get; set; } = string.Empty;

View file

@ -3,14 +3,11 @@ using System.Collections.Generic;
using System.ComponentModel.DataAnnotations.Schema;
using System.Text.Json;
using Volo.Abp.Domain.Entities.Auditing;
using Volo.Abp.MultiTenancy;
namespace Sozsoft.Platform.Entities;
public class CustomEndpoint : FullAuditedEntity<Guid>, IMultiTenant
public class CustomEndpoint : FullAuditedEntity<Guid>
{
public virtual Guid? TenantId { get; protected set; }
public string Name { get; set; }
public string Description { get; set; }
public string Url { get; set; } // GET, POST

View file

@ -2,20 +2,14 @@
using System.ComponentModel.DataAnnotations;
using Volo.Abp;
using Volo.Abp.Domain.Entities.Auditing;
using Volo.Abp.MultiTenancy;
namespace Sozsoft.Platform.Entities;
/// <summary>
/// Tenant bazında dinamik olarak tanımlanmış AppService'lerin kod ve meta verilerini saklar
/// </summary>
public class DynamicService : FullAuditedEntity<Guid>, IMultiTenant
public class DynamicService : FullAuditedEntity<Guid>
{
/// <summary>
/// Tenant ID - IMultiTenant implementasyonu
/// </summary>
public Guid? TenantId { get; set; }
/// <summary>
/// AppService'in benzersiz adı (örn: "DynamicCustomerService")
/// </summary>
@ -92,12 +86,10 @@ public class DynamicService : FullAuditedEntity<Guid>, IMultiTenant
public DynamicService(
Guid id,
string name,
string code,
Guid? tenantId = null) : base(id)
string code) : base(id)
{
Name = Check.NotNullOrWhiteSpace(name, nameof(name), maxLength: 256);
Code = Check.NotNullOrWhiteSpace(code, nameof(code));
TenantId = tenantId;
IsActive = true;
CompilationStatus = CompilationStatus.Pending;
Version = 1;

View file

@ -646,7 +646,7 @@ public class PlatformDbContext :
b.Property(x => x.OperationType).IsRequired().HasMaxLength(64);
b.Property(x => x.CsharpCode).IsRequired();
b.HasIndex(x => new { x.TenantId, x.EntityName, x.Method, x.Path }).IsUnique().HasFilter("[IsDeleted] = 0");
b.HasIndex(x => new { x.EntityName, x.Method, x.Path }).IsUnique().HasFilter("[IsDeleted] = 0");
});
builder.Entity<CustomEndpoint>(b =>
@ -663,7 +663,7 @@ public class PlatformDbContext :
b.Property(a => a.ParametersJson).HasColumnType("nvarchar(max)");
b.Property(a => a.PermissionsJson).HasColumnType("nvarchar(max)");
b.HasIndex(x => new { x.TenantId, x.Name }).IsUnique().HasFilter("[IsDeleted] = 0");
b.HasIndex(x => new { x.Name }).IsUnique().HasFilter("[IsDeleted] = 0");
});
builder.Entity<CustomComponent>(b =>
@ -682,8 +682,8 @@ public class PlatformDbContext :
// Data sekmesindeki endpoint listesi; adet ve url uzunlugu onceden bilinemez.
b.Property(x => x.DataSources).HasColumnType("nvarchar(max)");
b.HasIndex(x => new { x.TenantId, x.Name }).IsUnique().HasFilter("[IsDeleted] = 0");
b.HasIndex(x => new { x.TenantId, x.RoutePath }).IsUnique().HasFilter("[IsDeleted] = 0");
b.HasIndex(x => new { x.Name }).IsUnique().HasFilter("[IsDeleted] = 0");
b.HasIndex(x => new { x.RoutePath }).IsUnique().HasFilter("[IsDeleted] = 0");
});
builder.Entity<ReportCategory>(b =>
@ -1198,7 +1198,7 @@ public class PlatformDbContext :
b.Property(x => x.PrimaryEntityType).HasMaxLength(256);
b.Property(x => x.ControllerName).HasMaxLength(256);
b.HasIndex(x => new { x.TenantId, x.Name }).IsUnique().HasFilter("[IsDeleted] = 0");
b.HasIndex(x => new { x.Name }).IsUnique().HasFilter("[IsDeleted] = 0");
});
builder.Entity<Announcement>(b =>

View file

@ -13,7 +13,7 @@ using Volo.Abp.EntityFrameworkCore;
namespace Sozsoft.Platform.Migrations
{
[DbContext(typeof(PlatformDbContext))]
[Migration("20260831095952_Initial")]
[Migration("20260901075908_Initial")]
partial class Initial
{
/// <inheritdoc />
@ -1825,13 +1825,9 @@ namespace Sozsoft.Platform.Migrations
.HasMaxLength(256)
.HasColumnType("nvarchar(256)");
b.Property<Guid?>("TenantId")
.HasColumnType("uniqueidentifier")
.HasColumnName("TenantId");
b.HasKey("Id");
b.HasIndex("TenantId", "EntityName", "Method", "Path")
b.HasIndex("EntityName", "Method", "Path")
.IsUnique()
.HasFilter("[IsDeleted] = 0");
@ -1970,17 +1966,13 @@ namespace Sozsoft.Platform.Migrations
.HasMaxLength(512)
.HasColumnType("nvarchar(512)");
b.Property<Guid?>("TenantId")
.HasColumnType("uniqueidentifier")
.HasColumnName("TenantId");
b.HasKey("Id");
b.HasIndex("TenantId", "Name")
b.HasIndex("Name")
.IsUnique()
.HasFilter("[IsDeleted] = 0");
b.HasIndex("TenantId", "RoutePath")
b.HasIndex("RoutePath")
.IsUnique()
.HasFilter("[IsDeleted] = 0");
@ -2051,10 +2043,6 @@ namespace Sozsoft.Platform.Migrations
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<Guid?>("TenantId")
.HasColumnType("uniqueidentifier")
.HasColumnName("TenantId");
b.Property<string>("Url")
.IsRequired()
.HasMaxLength(256)
@ -2062,7 +2050,7 @@ namespace Sozsoft.Platform.Migrations
b.HasKey("Id");
b.HasIndex("TenantId", "Name")
b.HasIndex("Name")
.IsUnique()
.HasFilter("[IsDeleted] = 0");
@ -2601,10 +2589,6 @@ namespace Sozsoft.Platform.Migrations
.HasMaxLength(256)
.HasColumnType("nvarchar(256)");
b.Property<Guid?>("TenantId")
.HasColumnType("uniqueidentifier")
.HasColumnName("TenantId");
b.Property<int>("Version")
.ValueGeneratedOnAdd()
.HasColumnType("int")
@ -2612,7 +2596,7 @@ namespace Sozsoft.Platform.Migrations
b.HasKey("Id");
b.HasIndex("TenantId", "Name")
b.HasIndex("Name")
.IsUnique()
.HasFilter("[IsDeleted] = 0");

View file

@ -1130,7 +1130,6 @@ namespace Sozsoft.Platform.Migrations
columns: table => new
{
Id = table.Column<Guid>(type: "uniqueidentifier", nullable: false),
TenantId = table.Column<Guid>(type: "uniqueidentifier", nullable: true),
EntityName = table.Column<string>(type: "nvarchar(128)", maxLength: 128, nullable: false),
Method = table.Column<string>(type: "nvarchar(10)", maxLength: 10, nullable: false),
Path = table.Column<string>(type: "nvarchar(256)", maxLength: 256, nullable: false),
@ -1178,7 +1177,6 @@ namespace Sozsoft.Platform.Migrations
columns: table => new
{
Id = table.Column<Guid>(type: "uniqueidentifier", nullable: false),
TenantId = table.Column<Guid>(type: "uniqueidentifier", nullable: true),
Name = table.Column<string>(type: "nvarchar(128)", maxLength: 128, nullable: false),
RoutePath = table.Column<string>(type: "nvarchar(512)", maxLength: 512, nullable: false),
Code = table.Column<string>(type: "nvarchar(max)", nullable: false),
@ -1205,7 +1203,6 @@ namespace Sozsoft.Platform.Migrations
columns: table => new
{
Id = table.Column<Guid>(type: "uniqueidentifier", nullable: false),
TenantId = table.Column<Guid>(type: "uniqueidentifier", nullable: true),
Name = table.Column<string>(type: "nvarchar(128)", maxLength: 128, nullable: false),
Description = table.Column<string>(type: "nvarchar(512)", maxLength: 512, nullable: true),
Url = table.Column<string>(type: "nvarchar(256)", maxLength: 256, nullable: false),
@ -1339,7 +1336,6 @@ namespace Sozsoft.Platform.Migrations
columns: table => new
{
Id = table.Column<Guid>(type: "uniqueidentifier", nullable: false),
TenantId = table.Column<Guid>(type: "uniqueidentifier", nullable: true),
Name = table.Column<string>(type: "nvarchar(256)", maxLength: 256, nullable: false),
DisplayName = table.Column<string>(type: "nvarchar(512)", maxLength: 512, nullable: true),
Description = table.Column<string>(type: "nvarchar(2048)", maxLength: 2048, nullable: true),
@ -4113,9 +4109,9 @@ namespace Sozsoft.Platform.Migrations
filter: "[IsDeleted] = 0");
migrationBuilder.CreateIndex(
name: "IX_Sas_H_CrudEndpoint_TenantId_EntityName_Method_Path",
name: "IX_Sas_H_CrudEndpoint_EntityName_Method_Path",
table: "Sas_H_CrudEndpoint",
columns: new[] { "TenantId", "EntityName", "Method", "Path" },
columns: new[] { "EntityName", "Method", "Path" },
unique: true,
filter: "[IsDeleted] = 0");
@ -4127,23 +4123,23 @@ namespace Sozsoft.Platform.Migrations
filter: "[IsDeleted] = 0");
migrationBuilder.CreateIndex(
name: "IX_Sas_H_CustomComponent_TenantId_Name",
name: "IX_Sas_H_CustomComponent_Name",
table: "Sas_H_CustomComponent",
columns: new[] { "TenantId", "Name" },
column: "Name",
unique: true,
filter: "[IsDeleted] = 0");
migrationBuilder.CreateIndex(
name: "IX_Sas_H_CustomComponent_TenantId_RoutePath",
name: "IX_Sas_H_CustomComponent_RoutePath",
table: "Sas_H_CustomComponent",
columns: new[] { "TenantId", "RoutePath" },
column: "RoutePath",
unique: true,
filter: "[IsDeleted] = 0");
migrationBuilder.CreateIndex(
name: "IX_Sas_H_CustomEndpoint_TenantId_Name",
name: "IX_Sas_H_CustomEndpoint_Name",
table: "Sas_H_CustomEndpoint",
columns: new[] { "TenantId", "Name" },
column: "Name",
unique: true,
filter: "[IsDeleted] = 0");
@ -4167,9 +4163,9 @@ namespace Sozsoft.Platform.Migrations
filter: "[IsDeleted] = 0");
migrationBuilder.CreateIndex(
name: "IX_Sas_H_DynamicService_TenantId_Name",
name: "IX_Sas_H_DynamicService_Name",
table: "Sas_H_DynamicService",
columns: new[] { "TenantId", "Name" },
column: "Name",
unique: true,
filter: "[IsDeleted] = 0");

View file

@ -1822,13 +1822,9 @@ namespace Sozsoft.Platform.Migrations
.HasMaxLength(256)
.HasColumnType("nvarchar(256)");
b.Property<Guid?>("TenantId")
.HasColumnType("uniqueidentifier")
.HasColumnName("TenantId");
b.HasKey("Id");
b.HasIndex("TenantId", "EntityName", "Method", "Path")
b.HasIndex("EntityName", "Method", "Path")
.IsUnique()
.HasFilter("[IsDeleted] = 0");
@ -1967,17 +1963,13 @@ namespace Sozsoft.Platform.Migrations
.HasMaxLength(512)
.HasColumnType("nvarchar(512)");
b.Property<Guid?>("TenantId")
.HasColumnType("uniqueidentifier")
.HasColumnName("TenantId");
b.HasKey("Id");
b.HasIndex("TenantId", "Name")
b.HasIndex("Name")
.IsUnique()
.HasFilter("[IsDeleted] = 0");
b.HasIndex("TenantId", "RoutePath")
b.HasIndex("RoutePath")
.IsUnique()
.HasFilter("[IsDeleted] = 0");
@ -2048,10 +2040,6 @@ namespace Sozsoft.Platform.Migrations
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<Guid?>("TenantId")
.HasColumnType("uniqueidentifier")
.HasColumnName("TenantId");
b.Property<string>("Url")
.IsRequired()
.HasMaxLength(256)
@ -2059,7 +2047,7 @@ namespace Sozsoft.Platform.Migrations
b.HasKey("Id");
b.HasIndex("TenantId", "Name")
b.HasIndex("Name")
.IsUnique()
.HasFilter("[IsDeleted] = 0");
@ -2598,10 +2586,6 @@ namespace Sozsoft.Platform.Migrations
.HasMaxLength(256)
.HasColumnType("nvarchar(256)");
b.Property<Guid?>("TenantId")
.HasColumnType("uniqueidentifier")
.HasColumnName("TenantId");
b.Property<int>("Version")
.ValueGeneratedOnAdd()
.HasColumnType("int")
@ -2609,7 +2593,7 @@ namespace Sozsoft.Platform.Migrations
b.HasKey("Id");
b.HasIndex("TenantId", "Name")
b.HasIndex("Name")
.IsUnique()
.HasFilter("[IsDeleted] = 0");

View file

@ -48,13 +48,12 @@ public class DynamicAssemblyRegistrationService : BackgroundService, ITransientD
/// <summary>
/// Yeni assembly kaydı istemi
/// </summary>
public static void RequestAssemblyRegistration(Guid tenantId, Assembly assembly, string assemblyName)
public static void RequestAssemblyRegistration(Assembly assembly, string assemblyName)
{
lock (_lock)
{
_pendingRegistrations.Enqueue(new AssemblyRegistrationRequest
{
TenantId = tenantId,
Assembly = assembly,
AssemblyName = assemblyName,
RequestTime = DateTime.Now
@ -65,13 +64,12 @@ public class DynamicAssemblyRegistrationService : BackgroundService, ITransientD
/// <summary>
/// Bir servis adına ait assembly'nin Swagger/MVC'den kaldırılması istemi.
/// </summary>
public static void RequestAssemblyUnregistration(Guid tenantId, string serviceName)
public static void RequestAssemblyUnregistration(string serviceName)
{
lock (_lock)
{
_pendingUnregistrations.Enqueue(new AssemblyUnregistrationRequest
{
TenantId = tenantId,
ServiceName = serviceName,
RequestTime = DateTime.Now
});
@ -131,10 +129,7 @@ public class DynamicAssemblyRegistrationService : BackgroundService, ITransientD
try
{
var assemblyName = $"{service.Name}_{service.Version}";
await compiler.CompileAndRegisterForTenantAsync(
service.TenantId ?? Guid.Empty,
service.Code,
assemblyName);
await compiler.CompileAndRegisterAsync(service.Code, assemblyName);
}
catch (Exception ex)
{
@ -170,8 +165,7 @@ public class DynamicAssemblyRegistrationService : BackgroundService, ITransientD
}
catch (Exception ex)
{
_logger.LogError(ex, "Failed to unregister assembly. Tenant: {TenantId}, Service: {Service}",
request.TenantId, request.ServiceName);
_logger.LogError(ex, "Failed to unregister assembly. Service: {Service}", request.ServiceName);
}
}
@ -186,8 +180,7 @@ public class DynamicAssemblyRegistrationService : BackgroundService, ITransientD
}
catch (Exception ex)
{
_logger.LogError(ex, "Failed to register assembly. Tenant: {TenantId}, Assembly: {Assembly}",
request.TenantId, request.AssemblyName);
_logger.LogError(ex, "Failed to register assembly: {Assembly}", request.AssemblyName);
}
}
}
@ -219,15 +212,13 @@ public class DynamicAssemblyRegistrationService : BackgroundService, ITransientD
// DynamicServiceTypeRegistry'den kaldır
DynamicServiceTypeRegistry.UnregisterByAssemblyNamePrefix(servicePrefix);
// DynamicServiceCompiler tenant assembly cache'inden kaldır
DynamicServiceCompiler.UnregisterTenantAssemblyByPrefix(request.TenantId, servicePrefix);
// DynamicServiceCompiler assembly cache'inden kaldır
DynamicServiceCompiler.UnregisterAssemblyByPrefix(servicePrefix);
// MVC/Swagger'ı yenile
_changeProvider.NotifyChanges();
_logger.LogInformation(
"Assembly unregistered: {ServiceName} (Tenant: {TenantId})",
request.ServiceName, request.TenantId);
_logger.LogInformation("Assembly unregistered: {ServiceName}", request.ServiceName);
}
private async Task RegisterAssembly(AssemblyRegistrationRequest request)
@ -347,7 +338,6 @@ public class DynamicAssemblyRegistrationService : BackgroundService, ITransientD
private class AssemblyRegistrationRequest
{
public Guid TenantId { get; set; }
public Assembly Assembly { get; set; }
public string AssemblyName { get; set; }
public DateTime RequestTime { get; set; }
@ -355,7 +345,6 @@ public class DynamicAssemblyRegistrationService : BackgroundService, ITransientD
private class AssemblyUnregistrationRequest
{
public Guid TenantId { get; set; }
public string ServiceName { get; set; }
public DateTime RequestTime { get; set; }
}

View file

@ -451,16 +451,10 @@ public class PlatformHttpApiHostModule : AbpModule
var env = context.GetEnvironment();
// Setup delegate for dynamic service registration
DynamicServiceCompiler.NotifyAssemblyRegistration = (tenantId, assembly, assemblyName) =>
{
DynamicAssemblyRegistrationService.RequestAssemblyRegistration(tenantId, assembly, assemblyName);
};
DynamicServiceCompiler.NotifyAssemblyRegistration = DynamicAssemblyRegistrationService.RequestAssemblyRegistration;
// Setup delegate for dynamic service unregistration
DynamicServiceCompiler.NotifyAssemblyUnregistration = (tenantId, serviceName) =>
{
DynamicAssemblyRegistrationService.RequestAssemblyUnregistration(tenantId, serviceName);
};
DynamicServiceCompiler.NotifyAssemblyUnregistration = DynamicAssemblyRegistrationService.RequestAssemblyUnregistration;
if (env.IsDevelopment())
{