我在多租户环境中使用Web API。每个租户都有自己的数据库,结构相同。租户名称作为子域包含在URL中:http:// {tenant} .mysite.com / api / doodad / action
我已经编写了一个消息过滤器(DelegatingHandler)来提取租户名称并找到相应的数据库。我目前正在请求参数中存储此值。
几乎每个控制器操作都需要访问指向此数据库的DbContext。我没有使用存储库模式。我在DbContext上创建了第二个构造函数,它接受数据库名称。
我使用Unity在ApiController中注入DbContext的实例。如何让Unity调用DbContext上的第二个构造函数来传递请求参数中的值?
答案 0 :(得分:0)
我还没有尝试过,但我认为它应该有用......
您可以创建一个动作过滤器,将HttpRequestMessage添加到当前的分层容器中,然后使用InjectionFactory注册自定义DbContext类型以提取HttpRequestMessage并获取数据库名称。
这是一些未经测试的代码......
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, AllowMultiple = false)]
public class RegisterHttpRequestActionAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(HttpActionContext actionContext)
{
var container = GlobalConfiguration.Configuration.DependencyResolver.GetService(typeof(IUnityContainer)) as IUnityContainer;
container.RegisterInstance(actionContext.Request, new HierarchicalLifetimeManager());
}
}
和配置......
IUnityContainer rootContainer = new UnityContainer();
GlobalConfiguration.Configuration.DependencyResolver = new UnityHierarchicalDependencyResolver(rootContainer);
GlobalConfiguration.Configuration.Filters.Add(new RegisterHttpRequestActionAttribute());
rootContainer.RegisterType<MyDbContext>(new HierarchicalLifetimeManager(), new InjectionFactory(container =>
new MyDbContext(container.Resolve<HttpRequestMessage>().Properties["TenantDB"] as string)));
(仅供参考,我参考Unity.AspNet.WebApi NuGet包获取UnityHierarchicalDependencyResolver)