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

View file

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

View file

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

View file

@ -1,13 +1,10 @@
using System; using System;
using Volo.Abp.Domain.Entities.Auditing; using Volo.Abp.Domain.Entities.Auditing;
using Volo.Abp.MultiTenancy;
namespace Sozsoft.Platform.Entities; 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 EntityName { get; set; } = string.Empty;
public string Method { get; set; } = string.Empty; public string Method { get; set; } = string.Empty;
public string Path { get; set; } = string.Empty; public string Path { get; set; } = string.Empty;

View file

@ -1,13 +1,10 @@
using System; using System;
using Volo.Abp.Domain.Entities.Auditing; using Volo.Abp.Domain.Entities.Auditing;
using Volo.Abp.MultiTenancy;
namespace Sozsoft.Platform.Entities; 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 Name { get; set; } = string.Empty;
public string RoutePath { get; set; } = string.Empty; public string RoutePath { get; set; } = string.Empty;
public string Code { 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.ComponentModel.DataAnnotations.Schema;
using System.Text.Json; using System.Text.Json;
using Volo.Abp.Domain.Entities.Auditing; using Volo.Abp.Domain.Entities.Auditing;
using Volo.Abp.MultiTenancy;
namespace Sozsoft.Platform.Entities; 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 Name { get; set; }
public string Description { get; set; } public string Description { get; set; }
public string Url { get; set; } // GET, POST public string Url { get; set; } // GET, POST

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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