在已解析的子范围上设置活动租户
Set the active tenant on a resolved child scope
有没有办法在子作用域上设置活动租户?我认为它会产生全局影响,但它不会 在 子范围 (ILifetimeScope
) 已解决后。
依赖关系
<package id="Autofac" version="4.9.2" targetFramework="net471" />
<package id="Autofac.Multitenant" version="4.2.0" targetFramework="net471" />
复制
使用 .net 框架控制台应用程序和上面列出的依赖项编写的复制品。
using Autofac;
using Autofac.Multitenant;
namespace ConsoleAutoFacTenants
{
class Program
{
static void Main(string[] args)
{
var builder = new ContainerBuilder();
builder.RegisterType<GeneralReader>().As<IReader>().InstancePerDependency();
var appContainer = builder.Build();
var tenantIdentifier = new AutomationTenantStrategy();
var mtc = new MultitenantContainer(tenantIdentifier, appContainer);
mtc.ConfigureTenant("1", b => b.RegisterType<SpecificReader>().As<IReader>().InstancePerDependency());
// expected
var reader1 = mtc.Resolve<IReader>();
System.Diagnostics.Debug.Assert(reader1.Name == "General");
// unexpected result in debug.assert, assumed that reader2 would resolve type SpecificReader
var childScoped = mtc.BeginLifetimeScope();
tenantIdentifier.TenantId = "1";
var reader2 = childScoped.Resolve<IReader>();
System.Diagnostics.Debug.Assert(reader2.Name == "Specific");
}
}
internal sealed class AutomationTenantStrategy : ITenantIdentificationStrategy
{
public object TenantId { get; set; }
public bool TryIdentifyTenant(out object tenantId)
{
var activeTenant = this.TenantId;
if (TenantId == null)
{
tenantId = null;
return false;
}
tenantId = activeTenant;
return true;
}
}
public interface IReader
{
string Name { get; }
}
public sealed class GeneralReader : IReader
{
public string Name => "General";
}
public sealed class SpecificReader : IReader
{
public string Name => "Specific";
}
}
当您从作用域解析 ILifetimeScope
时,它会 return 自身,而不是创建子生命周期作用域。
这一行:
var childScoped = mtc.Resolve<ILifetimeScope>();
应替换为
var childScoped = mtc.BeginLifetimeScope();
创建新的 LifetimeScope 时,多租户模块会将 tenantId 设置为范围。在您的示例中,您必须在创建子 LifetimeScope
之前 "change" tenantId
tenantIdentifier.TenantId = "1";
var childScoped = mtc.BeginLifetimeScope();
解析后的 IReader
将是为租户指定的。
有没有办法在子作用域上设置活动租户?我认为它会产生全局影响,但它不会 在 子范围 (ILifetimeScope
) 已解决后。
依赖关系
<package id="Autofac" version="4.9.2" targetFramework="net471" />
<package id="Autofac.Multitenant" version="4.2.0" targetFramework="net471" />
复制
使用 .net 框架控制台应用程序和上面列出的依赖项编写的复制品。
using Autofac;
using Autofac.Multitenant;
namespace ConsoleAutoFacTenants
{
class Program
{
static void Main(string[] args)
{
var builder = new ContainerBuilder();
builder.RegisterType<GeneralReader>().As<IReader>().InstancePerDependency();
var appContainer = builder.Build();
var tenantIdentifier = new AutomationTenantStrategy();
var mtc = new MultitenantContainer(tenantIdentifier, appContainer);
mtc.ConfigureTenant("1", b => b.RegisterType<SpecificReader>().As<IReader>().InstancePerDependency());
// expected
var reader1 = mtc.Resolve<IReader>();
System.Diagnostics.Debug.Assert(reader1.Name == "General");
// unexpected result in debug.assert, assumed that reader2 would resolve type SpecificReader
var childScoped = mtc.BeginLifetimeScope();
tenantIdentifier.TenantId = "1";
var reader2 = childScoped.Resolve<IReader>();
System.Diagnostics.Debug.Assert(reader2.Name == "Specific");
}
}
internal sealed class AutomationTenantStrategy : ITenantIdentificationStrategy
{
public object TenantId { get; set; }
public bool TryIdentifyTenant(out object tenantId)
{
var activeTenant = this.TenantId;
if (TenantId == null)
{
tenantId = null;
return false;
}
tenantId = activeTenant;
return true;
}
}
public interface IReader
{
string Name { get; }
}
public sealed class GeneralReader : IReader
{
public string Name => "General";
}
public sealed class SpecificReader : IReader
{
public string Name => "Specific";
}
}
当您从作用域解析 ILifetimeScope
时,它会 return 自身,而不是创建子生命周期作用域。
这一行:
var childScoped = mtc.Resolve<ILifetimeScope>();
应替换为
var childScoped = mtc.BeginLifetimeScope();
创建新的 LifetimeScope 时,多租户模块会将 tenantId 设置为范围。在您的示例中,您必须在创建子 LifetimeScope
之前 "change" tenantIdtenantIdentifier.TenantId = "1";
var childScoped = mtc.BeginLifetimeScope();
解析后的 IReader
将是为租户指定的。