How to use AsyncController in MVC application using Ninject for DI?

Does anyone know how to use AsyncController in an mvc application that uses Ninject for DI?

AsyncController works great when I don't use ninject, but I can't get them to work together.

I added the following to my sitemodule, but did not go.

Bind<IAsyncController>( ).To<AsyncController>( ).InSingletonScope( ); 

sorry that I do not explain it in detail.

my controller is as follows

  [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( ); } } 

and my global.asax looks like this:

 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 ); } } 

this works great. but as soon as I use ninject (ninject 2.0), I get a 404 page error when I try to access the index page. this is how i configure 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( ) { } } 

Do I need to snap something on my sitemodule?

By the way, I use the example of Jeff Prosez, which he published on his blog. Here you can download his demo application and try Ninject-ify :)

Any help was appreciated.

+4
source share
2 answers

This does not seem to work because the standard NinjectControllerFactory inserts the NinjectActionInvoker into the ActionInvoker controller property. NinjectActionInvoker is obtained from ControllerActionInvoker . However, AsyncController uses ActionInvokers derived from AsyncControllerActionInvoker . for some reason, this causes the controller to not match the route, and returns a value of 404.

The real fix will be a patch for Ninject to support building AsyncController with AsyncControllerActionInvokers.

However, in the meantime, there is a workaround:

in your Global.asax add this override:

  protected override Ninject.Web.Mvc.NinjectControllerFactory CreateControllerFactory() { return new MyNinjectControllerFactory( kernel ); } 

and then add this class for 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; } } 

this is a copy of the NinjectControllerFactory that excludes the appointment of ActionInvoker.

If you have code that depends on the dependencies injected into your ActionFilters, you will need to create your own ActionInvoker, which returns AsyncControllerActionInvoker, which uses Ninject. Take a look at the source of Ninject.Web.Mvc for NinjectActionInvoker.

+2
source

As Dave said, a patch is needed for Ninject to support an asynchronous controller, and Remo says that he will work on it as soon as he ever appears. In the meantime, you can use the dave workaround or try this. it's straight from the horse’s mouth. I sent msg to ninject and Remo answered that.

AsyncControllers is not currently supported. I will add this as soon as I have time to implement it properly. At the same time, you can use apply the following changes to sources to add support:

  • Make a copy of the name NinjectActionInvoker, this is NinjectAsyncActionInvoker and change the base type to AsyncControllerActionInvoker

  • Apply the following changes to 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 "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 @@ namespace Ninject.Web.Mvc if (controller = = null) return base.GetControllerInstance (requestContext, controllerType);

    • var standardController = controller as controller;
    • var asyncController = controller as AsyncController;
    • if (asyncController! = null)
    • {
    • asyncController.ActionInvoker = CreateAsyncActionInvoker ();
    • }
    • else
    • {
    • var standardController = controller as controller;
    • 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); } 
    • }
      • ///
    • /// Creates an action invoker.
    • ///
    • /// Action invoker.
    • secure virtual NinjectAsyncActionInvoker CreateAsyncActionInvoker ()
    • {
    • return a new NinjectAsyncActionInvoker (core);
    • }
    • }} \ No newline at the end of the file

    • Remo

0
source

All Articles