[英]Custom resolve of registered type on runtime in multi-tenant architecture with Autofac
我遇到一个问题,我需要为Autofac中的已注册类型实现某种自定义解析器。
我的设置如下所示:
我有一个多租户架构,其中有多个数据库(每个租户一个,都共享相同的架构)。 一个应用程序需要遍历所有数据库以收集数据。
我想出了一个使用autofac注册DbContext的想法,但是当解决IEnumerable<DbContext>
我需要一种在运行时通过一些自定义代码来解决这些问题的方法,以便从另一个数据库中找出每个上下文的连接字符串。
我将尝试通过一些伪代码使其更加清晰:
private void Configure()
{
_container.RegisterType<DbContext>()
.ResolveBy(() => /*some custom code to resolve all DbContext based on the number of tenants*/);
}
public class MultiContextService
{
private readonly IEnumerable<DbContext> _dbContexts;
public MultiContextService(IEnumerable<DbContext> dbContexts )
{
_dbContexts = dbContexts;
}
public void SomeMethod()
{
foreach (var context in _dbContexts)
{
//do something to each context...
}
}
}
请注意 ,可以在运行时添加租户,并且应该能够解决租户而无需重新启动实例。
如果根本不注入DbContext,问题将变得容易得多。 而是为应用程序代码提供抽象,使您可以在运行时检索DbContext。 例如:
public interface IContextProvider {
IEnumerable<DbContext> Contexts { get; }
}
现在,您可以将将正确的DbContext集收集到IContextProvider
实现的问题了,但这将非常容易。
如果可能的话,请尝试隐藏一个事实,即您在抽象后面隐藏了一个DbContext
实例列表,这样就不必用foreach (var context in contexts)
方法来DbContext
应用程序代码。
如果需要运行时行为,则可以与程序集注册商合作。 如下所示:
using System;
using System.Collections.Generic;
using Autofac;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
var containerBuilder = new ContainerBuilder();
// customise your assembly loader for runtime behaviour
containerBuilder.RegisterAssemblyTypes(AppDomain.CurrentDomain.GetAssemblies())
.Where(t => t.BaseType == typeof(DbContext))
.As<DbContext>().OnPreparing(eventArgs =>
{
// depending on which context you are activating you can do use somekind of convention to get the correct connection string
});
containerBuilder.RegisterType<MultiContextService>();
var container = containerBuilder.Build();
var mcs = container.Resolve<MultiContextService>();
}
}
internal class MultiContextService
{
public MultiContextService(IEnumerable<DbContext> allContexts)
{
// all contexts are resolved here
}
}
internal abstract class DbContext
{
}
internal class DbContext1 : DbContext
{
}
internal class DbContext2 : DbContext
{
}
}
那行得通吗?
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.