如何在使用Ninject for DI的MVC应用程序中使用AsyncController?

时间:2010-09-29 16:47:42

标签: asp.net-mvc ninject asynccontroller

有没有人知道如何在使用Ninject进行DI的mvc应用程序中使用AsyncController?

当我不使用ninject时AsyncController工作正常,但我不能让它们一起工作。

我在sitemodule中添加了以下内容,但没有。

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页面未找到错误。这就是我配置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( )
        {

        }
    }

我是否需要在sitemodule上绑定任何内容?

BTW我正在使用他在博客Here 发布的Jeff Prosise的例子 你可以下载他的演示应用程序并尝试使用Ninject-ify:)

任何帮助表示感谢。

2 个答案:

答案 0 :(得分:2)

它似乎无法正常工作,因为标准的NinjectControllerFactory将NinjectActionInvoker插入到控制器的ActionInvoker属性中。 NinjectActionInvoker源自ControllerActionInvoker。但是,AsyncController使用从AsyncControllerActionInvoker派生的ActionInvokers。由于某种原因,这会导致控制器与路由不匹配,并返回404。

真正的修复将是Ninject的补丁,以支持使用AsyncControllerActionInvokers构建AsyncController。

然而,与此同时,这是一个解决方法:

在您的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,它返回使用Ninject的AsyncControllerActionInvoker。查看NinjectActionInvoker的Ninject.Web.Mvc源代码。

HTH

答案 1 :(得分:0)

就像戴夫指出的那样,Ninject需要一个补丁来支持异步控制器,Remo说他会在有一段时间后立即开始工作。同时你可以使用戴夫的解决方法或试试这个。这是从马的口直接。我在ninject组中发布了一个消息,Remo用这个回复了。

  

AsyncControllers目前不是   支持的。我会尽快加上这个   有时间实施它   正常。同时你可以使用   将以下更改应用于   来源添加支持:

     
      
  1. 将NinjectActionInvoker的副本命名为NinjectAsyncActionInvoker和   将基本类型更改为   AsyncControllerActionInvoker

  2.   
  3. 将以下更改应用于NinjectControllerFactory diff --git   “A / C:\用户\ REMOGL〜1 \应用程序数据\本地\ TEMP \   \ NinjectControllerFactory_HEAD.cs”   “B / C:\项目\ 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 @@名称空间   Ninject.Web.Mvc                       if(controller == null)                               return base.GetControllerInstance(requestContext,   controllerType);

         
        
    • var standardController = controller as   控制器;
    •   
    • var asyncController = controller as AsyncController;
    •   
    • if(asyncController!= null)
    •   
    • {
    •   
    • asyncController.ActionInvoker =   CreateAsyncActionInvoker();
    •   
    • }
    •   
    • else
    •   
    • {
    •   
    • var standardController = controller as   控制器;
    •   
    • 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); 
          } 
      
    •   
    • }
    •   
    •   
          
      • ///
      •   
    •   
    • ///创建动作调用者。
    •   
    • ///
    •   
    • ///动作调用者。
    •   
    • 受保护的虚拟NinjectAsyncActionInvoker   CreateAsyncActionInvoker()
    •   
    • {
    •   
    • 返回新的NinjectAsyncActionInvoker(内核);
    •   
    • }
    •   
    • }} \文件末尾没有换行符

    •   
    • 雷莫

    •   
  4.