Как использовать AsyncController в приложении MVC, используя Ninject для DI?
Кто-нибудь знает, как использовать AsyncController в приложении MVC, которое использует Ninject для DI?
AsyncController отлично работает, когда я не использую ninject, но я не могу заставить их работать вместе.
Я добавил следующий в мой модуль сайта, но не пошел.
Bind<IAsyncController>( ).To<AsyncController>( ).InSingletonScope( );
извините за то, что не объяснил это в деталях.
мой контроллер выглядит так
[HandleError]
public class HomeController : AsyncController
{
public void IndexAsync( )
{
AsyncManager.OutstandingOperations.Increment( );
RssFeed feed = new RssFeed( );
feed.GetRssFeedAsyncCompleted += ( s, e ) =>
{
AsyncManager.Parameters[ "items" ] = e.Items;
AsyncManager.OutstandingOperations.Decrement( );
};
feed.GetRssFeedAsync( "http://feeds.abcnews.com/abcnews/topstories" );
}
public ActionResult IndexCompleted( IEnumerable<SyndicationItem> items )
{
ViewData[ "SyndicationItems" ] = items;
return View( );
}
}
и мой global.asax выглядит так
public class MvcApplication : System.Web.HttpApplication
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = "" } // Parameter defaults
);
}
protected void Application_Start( )
{
AreaRegistration.RegisterAllAreas( );
RegisterRoutes( RouteTable.Routes );
}
}
это отлично работает но как только я использую ninject (ninject 2.0), я получаю ошибку 404 page not found, когда я пытаюсь получить доступ к странице индекса. это то, как я настраиваю ninject
public class MvcApplication : NinjectHttpApplication //System.Web.HttpApplication
{
#region IOC
static IKernel container;
public static IKernel Container
{
get
{
if ( container == null ) { container = new StandardKernel( new SiteModule( ) ); }
return container;
}
}
protected override IKernel CreateKernel( )
{
return Container;
}
#endregion
public static void RegisterRoutes( RouteCollection routes )
{
routes.IgnoreRoute( "{resource}.axd/{*pathInfo}" );
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = "" } // Parameter defaults
);
}
//protected void Application_Start()
//{
// AreaRegistration.RegisterAllAreas();
// RegisterRoutes(RouteTable.Routes);
//}
protected override void OnApplicationStarted( )
{
AreaRegistration.RegisterAllAreas( );
RegisterRoutes( RouteTable.Routes );
}
}
public class SiteModule : NinjectModule
{
public override void Load( )
{
}
}
Нужно ли что-нибудь связывать на моем сайте?
Кстати, я использую пример Джеффа Просиза, который он разместил в своем блоге. Здесь вы можете скачать его демонстрационное приложение и попробовать Ninject-ify it:)
Любая помощь приветствуется.
2 ответа
Похоже, что он не работает, потому что стандартный NinjectControllerFactory вставляет NinjectActionInvoker в свойство контроллера ActionInvoker. NinjectActionInvoker является производным от ControllerActionInvoker
, Однако AsyncController использует ActionInvokers, полученные из AsyncControllerActionInvoker
, по какой-то причине это заставляет контроллер не соответствовать маршруту, и он возвращает 404.
Настоящим исправлением будет патч для Ninject для поддержки построения AsyncController с AsyncControllerActionInvokers.
Однако, тем временем, есть обходной путь:
в вашем Global.asax добавьте это переопределение:
protected override Ninject.Web.Mvc.NinjectControllerFactory CreateControllerFactory()
{
return new MyNinjectControllerFactory( kernel );
}
и затем добавьте этот класс для MyNinjectControllerFactory:
public class MyNinjectControllerFactory : Ninject.Web.Mvc.NinjectControllerFactory
{
public MyNinjectControllerFactory( IKernel kernel ) : base( kernel ) { }
protected override IController GetControllerInstance( RequestContext requestContext, Type controllerType )
{
if ( controllerType == null )
{
// let the base handle 404 errors with proper culture information
return base.GetControllerInstance( requestContext, controllerType );
}
var controller = Kernel.TryGet( controllerType ) as IController;
if ( controller == null )
return base.GetControllerInstance( requestContext, controllerType );
//var standardController = controller as Controller;
//if ( standardController != null )
// standardController.ActionInvoker = CreateActionInvoker();
return controller;
}
}
это копия NinjectControllerFactory, которая исключает назначение ActionInvoker.
Если у вас есть код, который зависит от зависимостей, внедряемых в ваши ActionFilters, вам нужно будет создать свой собственный ActionInvoker, который возвращает AsyncControllerActionInvoker, который использует Ninject. Посмотрите на источник Ninject.Web.Mvc для NinjectActionInvoker.
НТН
Как сказал Дейв, для Ninject необходим патч для поддержки асинхронного контроллера, и Ремо говорит, что он поработает над ним, как только у него будет время. Тем временем вы можете использовать обходной путь Дейва или попробовать это. это прямо изо рта лошади. Я отправил сообщение в группе "Нинъект", и Ремо ответил этим.
AsyncControllers в настоящее время не поддерживаются. Я добавлю это, как только у меня будет время, чтобы реализовать это должным образом. В то же время вы можете применить следующие изменения к источникам, чтобы добавить поддержку:
Сделайте копию NinjectActionInvoker, назовите ее NinjectAsyncActionInvoker и измените базовый тип на AsyncControllerActionInvoker.
Примените следующие изменения к NinjectControllerFactory diff --git "a/C:\Users\REMOGL~1\AppData\Local\Temp\ \NinjectControllerFactory_HEAD.cs" "b/C:\Projects\Ninject\ \ninject.web.mvc\mvc2\src\Ninject.Web.Mvc\ \NinjectControllerFactory.cs" index 2c225a1..3916e4c 100644 --- "a/C:\Users\REMOGL~1\AppData\Local\Temp\ \NinjectControllerFactory_HEAD.cs" +++ "b/C:\Projects\Ninject\ninject.web.mvc\mvc2\src\ \Ninject.Web.Mvc\NinjectControllerFactory.cs" @@ -53,10 +53,18 @@ пространство имен Ninject.Web.Mvc if (controller == null) return base.GetControllerInstance (requestContext, controllerType);
- var standardController = контроллер в качестве контроллера;
- var asyncController = контроллер как AsyncController;
- if (asyncController! = null)
- {
- asyncController.ActionInvoker = CreateAsyncActionInvoker ();
- }
- еще
- {
- var standardController = контроллер в качестве контроллера;
- if (standardController! = null)
- standardController.ActionInvoker = CreateActionInvoker ();
}
if (standardController! = null)
standardController.ActionInvoker = CreateActionInvoker ();
return controller; } @@ -69,5 +77,14 @@ namespace Ninject.Web.Mvc { return new NinjectActionInvoker(Kernel); }
- }
- ///
- /// Создает действие invoker.
- ///
- /// Активист.
- защищенный виртуальный NinjectAsyncActionInvoker CreateAsyncActionInvoker ()
- {
- вернуть новый NinjectAsyncActionInvoker (Kernel);
- }
}} \ Нет новой строки в конце файла
Remo