4

DIにNinjectを使用するmvcアプリケーションでAsyncControllerを使用する方法を知っている人はいますか?

ninjectを使用しない場合、AsyncControllerは正常に機能しますが、それらを連携させることはできません。

サイトモジュールに以下を追加しましたが、うまくいきません。

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( )
        {

        }
    }

サイトモジュールに何かバインドする必要がありますか?

ところで、私は彼が彼のブログに投稿した Jeff Prosise の例を使用して ます。

どんな助けでも感謝します。

4

2 に答える 2

2

標準の NinjectControllerFactory がコントローラーの ActionInvoker プロパティに NinjectActionInvoker を挿入するため、機能していないようです。NinjectActionInvoker は から派生していControllerActionInvokerます。ただし、AsyncController は から派生した ActionInvokers を使用しAsyncControllerActionInvokerます。何らかの理由で、これによりコントローラーがルートと一致せず、404 が返されます。

本当の修正は、AsyncControllerActionInvokers を使用した AsyncController の構築をサポートする Ninject へのパッチです。

ただし、それまでの間、次の回避策があります。

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

これは、ActionInvoker の割り当てを省略した NinjectControllerFactory のコピーです。

ActionFilter に注入される依存関係に依存するコードがある場合は、Ninject を使用する AsyncControllerActionInvoker を返す独自の ActionInvoker を作成する必要があります。NinjectActionInvoker の Ninject.Web.Mvc ソースを見てください。

于 2010-10-01T16:00:54.693 に答える
0

dave が指摘したように、Ninject が async コントローラーをサポートするにはパッチが必要であり、Remo は、彼がいつか手に入れたらすぐにそれに取り組むと言っています。それまでの間、デイブの回避策を使用するか、これを試すことができます。これは馬の口から直接です。私は ninject グループにメッセージを投稿し、Remo はこれで応答しました。

AsyncControllers は現在サポートされていません。適切に実装する時間ができ次第、これを追加します。それまでの間、次の変更をソースに適用してサポートを追加できます。

  1. NinjectActionInvoker のコピーを作成し、それに NinjectAsyncActionInvoker という名前を付け、ベース タイプを AsyncControllerActionInvoker に変更します。

  2. 次の変更を 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 @@ 名前空間 Ninject.Web.Mvc の場合(コントローラー == null) return base.GetControllerInstance(requestContext, controllerType);

    • var standardController = Controller as Controller;
    • var asyncController = AsyncController としてのコントローラー。
    • if (asyncController != null)
    • {
    • asyncController.ActionInvoker = CreateAsyncActionInvoker();
    • }
    • そうしないと
    • {
    • 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); 
          } 
      
    • }
      • ///
    • /// アクション呼び出し元を作成します。
    • ///
    • /// アクションの呼び出し元。
    • 保護された仮想 NinjectAsyncActionInvoker CreateAsyncActionInvoker()
    • {
    • 新しい NinjectAsyncActionInvoker(Kernel) を返します。
    • }
    • } } \ ファイルの最後に改行はありません

    • レモ

于 2010-10-02T12:14:06.557 に答える