我正在尝试开发一个多租户项目,其中每个客户都可以拥有自己的特定视图引擎。
具体来说,我想将视图编译为 DLL(使用RazorEngine)并RazorViewEngine
为每个客户端设置一个单独的视图,但如果找不到匹配的视图,也可以提供对标准的回退RazorViewEngine
,就像 MVC 框架在您有多个视图引擎时所做的那样指定的。
我发现我可以在Global.asax
我的 MVC 4 项目中使用 autofac 注入视图引擎,方法是:
ViewEngines.Engines.Clear();
var builder = new ContainerBuilder();
builder.RegisterType<WebFormViewEngine>().As<IViewEngine>();
现在我还想提供如上所述的租户特定覆盖,我可以使用以下代码来完成:
var mtc = new MultitenantContainer(tenantIdStrategy, builder.Build());
mtc.ConfigureTenant("Client1", b => b.RegisterType<RazorViewEngine>().As<IViewEngine>());
DependencyResolver.SetResolver(new AutofacDependencyResolver(mtc));
在此示例代码中,我只是想看看是否可以将 设置WebFormsViewEngine
为后备,然后RazorViewEngine
为特定租户启用 。
在加载并浏览到非租户 url 时,mvc 将按预期仅解析 WebFormsViewEngine(通过调用DependencyResolver
并依次调用 Autofac),这按预期工作,但是当我访问一个也包含RazorViewEngine
未找到视图的 url 时,即使存在有效的剃刀视图。
相反,如果我停止 IISExpress 或执行某些操作来生成应用程序池回收并首先访问可租用的 url,则两个视图引擎都已注册。
据我所知,MVC 缓存了在第一次调用MultiServiceResolver后检索到的视图引擎列表。
internal IViewEngine[] CombinedItems
{
get
{
IViewEngine[] combinedItems = _combinedItems;
if (combinedItems == null)
{
combinedItems = MultiServiceResolver.GetCombined<IViewEngine>(Items, _dependencyResolver);
_combinedItems = combinedItems;
}
return combinedItems;
}
}
有没有办法覆盖这种缓存或另一种更好的方法来实现我想要在这里实现的目标?