diff --git a/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/Entity.cs b/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/Entity.cs
index cf1b643305..274b4584d1 100644
--- a/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/Entity.cs
+++ b/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/Entity.cs
@@ -7,6 +7,11 @@ namespace Volo.Abp.Domain.Entities
[Serializable]
public abstract class Entity : IEntity
{
+ protected Entity()
+ {
+ EntityHelper.TrySetTenantId(this);
+ }
+
///
public override string ToString()
{
diff --git a/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/EntityHelper.cs b/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/EntityHelper.cs
index 4725496a29..e2acfba87c 100644
--- a/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/EntityHelper.cs
+++ b/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/EntityHelper.cs
@@ -265,5 +265,25 @@ namespace Volo.Abp.Domain.Entities
? new Type[] { typeof(DisableIdGenerationAttribute) }
: new Type[] { });
}
+
+ public static void TrySetTenantId(IEntity entity)
+ {
+ if (entity is not IMultiTenant multiTenantEntity)
+ {
+ return;
+ }
+
+ var tenantId = AsyncLocalCurrentTenantAccessor.Instance.Current?.TenantId;
+ if (tenantId == multiTenantEntity.TenantId)
+ {
+ return;
+ }
+
+ ObjectHelper.TrySetProperty(
+ multiTenantEntity,
+ x => x.TenantId,
+ () => tenantId
+ );
+ }
}
}
diff --git a/framework/src/Volo.Abp.MultiTenancy/Volo/Abp/MultiTenancy/AbpMultiTenancyModule.cs b/framework/src/Volo.Abp.MultiTenancy/Volo/Abp/MultiTenancy/AbpMultiTenancyModule.cs
index c51daf99aa..1a39248631 100644
--- a/framework/src/Volo.Abp.MultiTenancy/Volo/Abp/MultiTenancy/AbpMultiTenancyModule.cs
+++ b/framework/src/Volo.Abp.MultiTenancy/Volo/Abp/MultiTenancy/AbpMultiTenancyModule.cs
@@ -18,6 +18,8 @@ namespace Volo.Abp.MultiTenancy
{
public override void ConfigureServices(ServiceConfigurationContext context)
{
+ context.Services.AddSingleton(AsyncLocalCurrentTenantAccessor.Instance);
+
var configuration = context.Services.GetConfiguration();
Configure(configuration);
}
diff --git a/framework/src/Volo.Abp.MultiTenancy/Volo/Abp/MultiTenancy/AsyncLocalCurrentTenantAccessor.cs b/framework/src/Volo.Abp.MultiTenancy/Volo/Abp/MultiTenancy/AsyncLocalCurrentTenantAccessor.cs
index 32f7fc0782..279e585d26 100644
--- a/framework/src/Volo.Abp.MultiTenancy/Volo/Abp/MultiTenancy/AsyncLocalCurrentTenantAccessor.cs
+++ b/framework/src/Volo.Abp.MultiTenancy/Volo/Abp/MultiTenancy/AsyncLocalCurrentTenantAccessor.cs
@@ -3,8 +3,10 @@ using Volo.Abp.DependencyInjection;
namespace Volo.Abp.MultiTenancy
{
- public class AsyncLocalCurrentTenantAccessor : ICurrentTenantAccessor, ISingletonDependency
+ public class AsyncLocalCurrentTenantAccessor : ICurrentTenantAccessor
{
+ public static AsyncLocalCurrentTenantAccessor Instance { get; } = new();
+
public BasicTenantInfo Current
{
get => _currentScope.Value;
@@ -13,7 +15,7 @@ namespace Volo.Abp.MultiTenancy
private readonly AsyncLocal _currentScope;
- public AsyncLocalCurrentTenantAccessor()
+ private AsyncLocalCurrentTenantAccessor()
{
_currentScope = new AsyncLocal();
}
diff --git a/framework/test/Volo.Abp.Ddd.Tests/Volo/Abp/Domain/Entities/Entity_Tests.cs b/framework/test/Volo.Abp.Ddd.Tests/Volo/Abp/Domain/Entities/Entity_Tests.cs
index 779ac3fe49..36c65c63a4 100644
--- a/framework/test/Volo.Abp.Ddd.Tests/Volo/Abp/Domain/Entities/Entity_Tests.cs
+++ b/framework/test/Volo.Abp.Ddd.Tests/Volo/Abp/Domain/Entities/Entity_Tests.cs
@@ -74,6 +74,23 @@ namespace Volo.Abp.Domain.Entities
new Car(42, tenantId1).EntityEquals(new Car(42, tenantId1)).ShouldBeTrue();
}
+ [Fact]
+ public void Should_Set_TenantId_On_Object_Creation()
+ {
+ var tenantId = Guid.NewGuid();
+ AsyncLocalCurrentTenantAccessor.Instance.Current = new BasicTenantInfo(tenantId);
+ new Car().TenantId.ShouldBe(tenantId);
+ }
+
+ [Fact]
+ public void Should_Override_TenantId_Manually()
+ {
+ AsyncLocalCurrentTenantAccessor.Instance.Current = null;
+
+ var tenantId = Guid.NewGuid();
+ new Car(0, tenantId).TenantId.ShouldBe(tenantId);
+ }
+
public class Person : Entity
{
public Person()
@@ -88,7 +105,7 @@ namespace Volo.Abp.Domain.Entities
public class Car : Entity, IMultiTenant
{
- public Guid? TenantId { get; }
+ public Guid? TenantId { get; private set; }
public Car()
{
diff --git a/framework/test/Volo.Abp.TestApp.Tests/Volo/Abp/TestApp/Application/PersonAppService_Tests.cs b/framework/test/Volo.Abp.TestApp.Tests/Volo/Abp/TestApp/Application/PersonAppService_Tests.cs
index 8d205df899..d723184b95 100644
--- a/framework/test/Volo.Abp.TestApp.Tests/Volo/Abp/TestApp/Application/PersonAppService_Tests.cs
+++ b/framework/test/Volo.Abp.TestApp.Tests/Volo/Abp/TestApp/Application/PersonAppService_Tests.cs
@@ -57,7 +57,7 @@ namespace Volo.Abp.TestApp.Application
var uniquePersonName = Guid.NewGuid().ToString();
var personDto = await _peopleAppService.CreateAsync(new PersonDto {Name = uniquePersonName});
- var repository = ServiceProvider.GetService>();
+ var repository = ServiceProvider.GetRequiredService>();
var person = await repository.FindAsync(personDto.Id);
person.ShouldNotBeNull();