我还没有找到在 C# 中使用通用主机的多租户解决方案(或示例)。
Autofac 存储库(ConsoleApp、MVC 和 WCF)中给出的示例使用了通用主机不支持的策略(据我所知)(Autofac 需要访问 IContainer 实例来创建多租户容器)。
有没有办法通过通用主机和 Autofac 使用多租户?
谢谢!
我已经阅读了 Autofac github 存储库中的示例并进行了一些实验,但没有找到解决方案。
这是示例的链接
更具体地说,这是一个标准的通用主机示例,来自实验时的代码,我已经添加了注释来突出显示当前的问题
using Autofac;
using Autofac.Extensions.DependencyInjection;
using Autofac.Multitenant;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
namespace AutoFacMultiTenantExploration;
internal class Program
{
static async Task Main(string[] args)
{
AutofacServiceProviderFactory factory = new();
var host = Host.CreateDefaultBuilder(args)
.UseServiceProviderFactory(factory)
.ConfigureServices(ConfigureServices)
.ConfigureContainer<ContainerBuilder>(ConfigureContainer)
.UseConsoleLifetime()
.Build();
//var mtc = new MultitenantContainer(_myTenantIdentificationStrategy, IContainer instance needed here...);
await host.RunAsync();
}
private static void ConfigureServices(HostBuilderContext context, IServiceCollection collection)
{
//var mtc = new MultitenantContainer(_myTenantIdentificationStrategy, IContainer instance needed here...);
collection.AddHostedService<HostedService>();
collection.AddSingleton<MyTenantIdentificationStrategy>();
}
private static void ConfigureContainer(HostBuilderContext context, ContainerBuilder builder)
{
//var mtc = new MultitenantContainer(_myTenantIdentificationStrategy, IContainer instance needed here...);
builder.RegisterType<Logger>().As<ILogger>();
}
}
// IContainer is not registered by the generic host, so it's not possible to inject an instance here with the service IHostedService
internal class HostedService(ILogger logger) : IHostedService
{
private readonly ILogger _logger = logger;
public Task StartAsync(CancellationToken cancellationToken)
{
_logger.LogInformation("Starting hosted service");
//var mtc = new MultitenantContainer(_myTenantIdentificationStrategy, IContainer instance needed here...);
return Task.CompletedTask;
}
public Task StopAsync(CancellationToken cancellationToken)
{
_logger.LogInformation("Stopping hosted service");
return Task.CompletedTask;
}
}
internal class Logger : ILogger
{
public void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception? exception, Func<TState, Exception?, string> formatter)
{
Console.Out.WriteLineAsync($"Logger: {formatter.Invoke(state, exception)}");
}
public bool IsEnabled(LogLevel logLevel)
{
throw new NotImplementedException();
}
public IDisposable? BeginScope<TState>(TState state) where TState : notnull
{
throw new NotImplementedException();
}
}
internal class MyTenantIdentificationStrategy : ITenantIdentificationStrategy
{
public int Identity { get; set; } = 0;
public bool TryIdentifyTenant(out object? tenantId)
{
tenantId = Identity;
return true;
}
}
ASP.NET Core 集成的文档展示了它是如何工作的,但您可能需要根据您的需求对其进行一些调整。 Autofac.AspNetCore.Multitenant 包是关键。
例如,你可以这样做:
public static class Program
{
public static async Task Main(string[] args)
{
await Host.CreateDefaultBuilder(args)
.UseServiceProviderFactory(
new AutofacMultitenantServiceProviderFactory(ConfigureMultitenantContainer))
.ConfigureServices(ConfigureServices)
.ConfigureContainer<ContainerBuilder>(ConfigureContainer)
.RunConsoleAsync();
}
private static void ConfigureServices(IServiceCollection services)
{
// Register things with MS DI.
}
private static void ConfigureContainer(ContainerBuilder containerBuilder)
{
// Register things that are shared across all tenants.
}
private static MultitenantContainer ConfigureMultitenantContainer(IContainer container)
{
var strategy = new YourTenantIdStrategy();
var multitenantContainer = new MultitenantContainer(strategy, container);
// Register things for various tenants.
return multitenantContainer;
}
}