【发布时间】:2018-10-01 15:59:31
【问题描述】:
我有一个基本的抽象上下文,它有几百个共享对象,然后是 2 个“实现”上下文,它们都从基础继承并被设计为供 .net 核心应用程序中的不同租户使用。一个租户对象被注入到 OnConfiguring 的构造函数中以获取要使用的连接字符串。
public abstract class BaseContext : DbContext
{
protected readonly AppTenant Tenant;
protected BaseContext (AppTenant tenant)
{
Tenant = tenant;
}
}
public TenantOneContext : BaseContext
{
public TenantOneContext(AppTenant tenant)
: base(tenant)
{
}
}
在 startup.cs 中,我像这样注册 DbContexts:
services.AddDbContext<TenantOneContext>();
services.AddDbContext<TenantTwoContext>();
然后使用 autofac 容器和 th Multitenant 包,我像这样注册特定于租户的上下文:
IContainer container = builder.Build();
MultitenantContainer mtc = new MultitenantContainer(container.Resolve<ITenantIdentificationStrategy>(), container);
mtc.ConfigureTenant("1", config =>
{
config.RegisterType<TenantOneContext>().AsSelf().As<BaseContext>();
});
mtc.ConfigureTenant("2", config =>
{
config.RegisterType<TenantTwoContext>().AsSelf().As<BaseContext>();
});
Startup.ApplicationContainer = mtc;
return new AutofacServiceProvider(mtc);
我的服务层是围绕被注入的 BaseContext 设计的,以便在可能的情况下重用,然后需要特定功能的服务使用 TenantContexts。
public BusinessService
{
private readonly BaseContext _baseContext;
public BusinessService(BaseContext context)
{
_baseContext = context;
}
}
在运行时的上述服务中,我得到一个异常“无法使用构造函数查找器'Autofac.Core.Activators.Reflection.DefaultConstructorFinder'找到类型'BaseContext'的构造函数”。我不知道为什么这被打破了...... AppTenant 肯定是创建的,因为我可以成功地将它注入其他地方。如果我添加一个额外的注册,我可以让它工作:
builder.RegisterType<TenantOneContext>().AsSelf().As<BaseContext>();
我不明白为什么租户容器注册需要上述注册才能工作。这对我来说似乎坏了;在结构映射(Saaskit)中,我能够在不添加额外注册的情况下做到这一点,并且我假设使用内置的 AddDbContext 注册将负责为要覆盖的容器创建默认注册。我是否在这里遗漏了什么,或者这可能是 autofac 的多租户功能中的错误?
更新:
这里是问题的完全可运行的 repo:https://github.com/danjohnso/testapp
如果我有第 53/54 行和第 82-90 行,为什么需要 Startup.cs 的第 66 行?
【问题讨论】:
-
从这个解释中不清楚你在解决这个问题时在做什么以及正在创建哪些范围。请创建一个最小、完整和可验证的示例,如下所述:stackoverflow.com/help/mcve
-
AddDbConetxt(和常规注册)使用接受DbContextOptions/DbContextOptions<T>的构造函数。您是否尝试将您的构造函数重新声明为protected BaseContext (DbContextOptions options, AppTenant tenant) : base(options)) -
@Tseng 你可以,但是我需要使用 OnConfiguring 来覆盖上下文中的一些其他行为,这就是我说我正在使用它的原因。 alexander-leonov 不可能将整个应用程序分解为一个可运行的示例。我已经为熟悉 autofac 的人提供了所有正在使用的部分和相关代码的有效解释,以便为我提供有关此行为的一些指导
-
你仍然可以这样做 iirc。在任何情况下都会调用
OnConfiguring,无论您是否使用DbContextOptions构造函数构造它。您可以在OnConfiguring中使用IsConfigured来查看它是否已通过DbContextOptions进行配置。见remarks in the docs -
@Dan - 发现问题,今晚将发布我的答案。回购实际上帮了很多忙。
标签: asp.net-core entity-framework-core autofac multi-tenant