#asp.net-mvc-3 #ninject #viewengine
#asp.net-mvc-3 #ninject #viewengine
Вопрос:
Я хочу внедрить пользовательский ViewEngine на мой веб-сайт MVC. Это то, что я делаю:
private static IKernel CreateKernel()
{
kernel.Bind<IViewEngine>().ToProvider(new RazorViewEngineProvider()).InRequestScope();
}
Это мой провайдер:
public class RazorViewEngineProvider : Provider<RazorViewEngine>
{
protected override RazorViewEngine CreateInstance(IContext context)
{
return new RazorViewEngine();
}
}
Проблема в том, что мой провайдер вызывается только один раз, когда я захожу на веб-сайт в первый раз. В следующий раз мой провайдер каким-то образом все еще находится в кэше. И это не то, чего я хочу.
Я хочу, чтобы поставщик выполнялся при каждом запросе. Я думал, что смогу это сделать.InRequestScope(), но это не имеет никакого значения. Кто-нибудь знает, что происходит?
Ответ №1:
В этом случае механизм просмотра не кэшируется Ninject. Сам MVC не запрашивает его каждый раз из IDependencyResolver. Но я думаю, что это правильное поведение. Таким образом, он сводит к минимуму накладные расходы на создание механизма просмотра путем его повторного использования.
У вас не должно быть зависимой от запроса зависимости в вашем механизме просмотра. Этот вид зависимости должен быть извлечен из модели представления и должен быть назначен контроллером.
И вы должны удалить InRequestScope. В противном случае он будет удален Ninject после первого запроса, но MVC все равно попытается его повторно использовать.
Комментарии:
1. Я пытаюсь кое-что сделать для многопользовательского веб-сайта. Я хочу иметь разные темы. Таким образом, у каждого тенанта есть свой собственный css и masterpage. Я подумал, что было бы неплохо обнаруживать теннант при каждом запросе и создавать viewengine с его помощью.
Ответ №2:
Вместо того, чтобы вводить пользовательский механизм просмотра, не могли бы вы попробовать использовать Application_Start()
вместо этого:
protected void Application_Start()
{
ViewEngines.Engines.Clear();
ViewEngines.Engines.Add(new RazorViewEngineProvider());
RegisterRoutes(RouteTable.Routes);
}
Что происходит, когда вы выполняете регистрацию таким образом? Работает ли это?
Комментарии:
1. Да, такая регистрация работает. Но это не совсем то, что я хочу. Я хочу обновлять ViewEngine при каждом запросе. Я рассмотрел методы global_asax, из которых BeginRequest выглядит наиболее актуальным. Но я хотел бы использовать зависимость от Ninject, и я не могу получить доступ к ядру Ninject из global_asax.
2. Я повторил вашу проблему, действительно,
CreateInstance
метод вызывается только один раз и для меня. Боюсь, я не уверен в этом.