injecting changing view engine list
I'm trying to develop a multi-tenancy project wherein each client can have
their own specific view engines.
Specifically I'd like to compile the views to a DLL (using RazorEngine)
and have an individual RazorViewEngine for each client but also provide a
fallback to the standard RazorViewEngine if no matching views are found,
just as the MVC framework does if you have multiple view engines
specified.
I have found I can inject view engines using autofac in the Global.asax of
my MVC 4 project using:
ViewEngines.Engines.Clear();
var builder = new ContainerBuilder();
builder.RegisterType<WebFormViewEngine>().As<IViewEngine>();
Now I also want to provide tenant specific overrides as mentioned above
which I can do with the following code:
var mtc = new MultitenantContainer(tenantIdStrategy, builder.Build());
mtc.ConfigureTenant("Client1", b =>
b.RegisterType<RazorViewEngine>().As<IViewEngine>());
DependencyResolver.SetResolver(new AutofacDependencyResolver(mtc));
In this example code I just wanted to see if I could set the
WebFormsViewEngine as a fallback and then enable the RazorViewEngine for a
specific tenant.
Upon loading and browsing to a non-tenant url, mvc will resolve just the
WebFormsViewEngine as expected (through calling the DependencyResolver and
in turn Autofac), this works as expected however when I then visit a url
that would also include the RazorViewEngine no views are found, even
though a valid razor view exists.
Conversely if I stop IISExpress or do something to generate an app pool
recycle and visit a tenantable url first both view engines are registered.
From what I can tell MVC caches the list of view engines retrieved after
the first call to the MultiServiceResolver.
internal IViewEngine[] CombinedItems
{
get
{
IViewEngine[] combinedItems = _combinedItems;
if (combinedItems == null)
{
combinedItems =
MultiServiceResolver.GetCombined<IViewEngine>(Items,
_dependencyResolver);
_combinedItems = combinedItems;
}
return combinedItems;
}
}
Is there a way to override this caching or another better way to achieve
what I'm trying to get here?
No comments:
Post a Comment