web-dev-qa-db-ja.com

ASP.NET MVC4のNinject

だから私は多くのねじ込みの後、私はようやくNinjectをMVC4アプリケーションに接続してコンパイルしました。私が遭遇していた問題は、IDependencyScopeインターフェイスが私が知ることができるものからもはや存在せず、System.Web.Http.Dependencies名前空間が廃止されたことです。

だから、今私の問題は、すべてが配線されており、アプリケーションを実行すると、次のようになります:

    Sequence contains no elements

    [InvalidOperationException: Sequence contains no elements]
   System.Linq.Enumerable.Single(IEnumerable`1 source) +379
   Ninject.Web.Mvc.NinjectMvcHttpApplicationPlugin.Start() in c:\Projects\Ninject\ninject.web.mvc\mvc3\src\Ninject.Web.Mvc\NinjectMvcHttpApplicationPlugin.cs:53
   Ninject.Web.Common.Bootstrapper.<Initialize>b__0(INinjectHttpApplicationPlugin c) in c:\Projects\Ninject\Ninject.Web.Common\src\Ninject.Web.Common\Bootstrapper.cs:52
   Ninject.Infrastructure.Language.ExtensionsForIEnumerableOfT.Map(IEnumerable`1 series, Action`1 action) in c:\Projects\Ninject\ninject\src\Ninject\Infrastructure\Language\ExtensionsForIEnumerableOfT.cs:31
   Ninject.Web.Common.Bootstrapper.Initialize(Func`1 createKernelCallback) in c:\Projects\Ninject\Ninject.Web.Common\src\Ninject.Web.Common\Bootstrapper.cs:53
   Ninject.Web.Common.NinjectHttpApplication.Application_Start() in c:\Projects\Ninject\Ninject.Web.Common\src\Ninject.Web.Common\NinjectHttpApplication.cs:81

私はそれを追跡することができなかったか、それがどこから来ているのかを理解することさえできませんでした。

Global.asax.cs内の標準のNinjectメソッドは次のようになります。

        protected override IKernel CreateKernel()
        {
            var kernel = new StandardKernel();
            kernel.Load(Assembly.GetExecutingAssembly());
            kernel.Bind<IRenderHelper>().To<RenderHelper>();

            GlobalConfiguration.Configuration.ServiceResolver.SetResolver(new NinjectDependencyResolver(kernel));
            return kernel;
        }

        protected override void OnApplicationStarted()
        {
            base.OnApplicationStarted();
            AreaRegistration.RegisterAllAreas();
            RegisterGlobalFilters(GlobalFilters.Filters);
            RegisterRoutes(RouteTable.Routes);
            BundleTable.Bundles.RegisterTemplateBundles();
        }

そして私のカスタムリゾルバー:

public class NinjectDependencyResolver : IDependencyResolver
{
    private readonly IKernel _kernel;

    public NinjectDependencyResolver(IKernel kernel)
    {
        _kernel = kernel;
    }

    public object GetService(Type serviceType)
     {
         return _kernel.TryGet(serviceType);
     }

     public IEnumerable<object> GetServices(Type serviceType)
     {
         try
         {
             return _kernel.GetAll(serviceType);
         }
         catch (Exception)
         {
             return new List<object>();
         }
     }

     public void Dispose()
     {
         // When BeginScope returns 'this', the Dispose method must be a no-op.
     }
}

ここでどんな洞察もいただければ幸いです。私は.NET 4.5で実行されている最新のMVC4 RCにDIフレームワークを接続しようとすることにあまりにも多くの時間を費やしてきましたが、まったく機能しないものの許容レベルに達しました。

Edit#1githubでExtensionsForIEnumerableOfT.csを掘り下げてさらに調査しても、あまり役に立たない:

https://github.com/ninject/ninject/blob/master/src/Ninject/Infrastructure/Language/ExtensionsForIEnumerableOfT.cs

そして、もし私が自分で書いたとしたら、私はこれを理解し始めるでしょうが、Bootstrapper.csもあまり役に立ちません。

https://github.com/ninject/Ninject.Web.Common/blob/master/src/Ninject.Web.Common/Bootstrapper.cs

これらの詳細を願って、Ninjectの経験が豊富な方にとって、より簡単になるでしょう。

Edit#2発生したエラーは特にNinjectMvcHttpApplicationPlugin.csにあります:

問題のある行は次のとおりです。

ModelValidatorProviders.Providers.Remove(ModelValidatorProviders.Providers.OfType<DataAnnotationsModelValidatorProvider>().Single());

これは次のメソッドに住んでいます:

public void Start()
{
    ModelValidatorProviders.Providers.Remove(ModelValidatorProviders.Providers.OfType<DataAnnotationsModelValidatorProvider>().Single());
    DependencyResolver.SetResolver(this.CreateDependencyResolver());
    RemoveDefaultAttributeFilterProvider();
}

ModelValidatorProvidersコレクションには2つの要素が含まれています:{System.Web.Mvc.DataErrorInfoModelValidatorProvider} {System.Web.Mvc.ClientDataTypeModelValidatorProvider}

そして、それは以下の単一のインスタンスを削除しようとしています:

System.Web.Mvc.DataAnnotationsModelValidatorProvider

ModelValidationProviders.Providersコレクションにロードされていないようです。ここから何かアイデアはありますか?

上記の例外から次の例外への解決策

ModelValidatorProvidersの問題を解決するには、予期していたオブジェクトを手動で追加する必要がありました。したがって、私のCreateKernelメソッドは次のようになります。

protected override IKernel CreateKernel()
{
    var kernel = new StandardKernel();
    kernel.Load(Assembly.GetExecutingAssembly());

    kernel.Bind<IRenderHelper>().To<RenderHelper>();
    kernel.Unbind<IDocumentViewerAdapter>();

    GlobalConfiguration.Configuration.ServiceResolver.SetResolver(new NinjectDependencyResolver(kernel));
    ModelValidatorProviders.Providers.Add(new DataAnnotationsModelValidatorProvider());
    FilterProviders.Providers.Add(new FilterAttributeFilterProvider());
    return kernel;
}

今度はそれが実行されてNinjectの実際の根性に入りますが、まだ問題があり、再び意味がありません。

Exception Details: Ninject.ActivationException: Error activating IntPtr
No matching bindings are available, and the type is not self-bindable.
Activation path:
 3) Injection of dependency IntPtr into parameter method of constructor of type Func{IKernel}
 2) Injection of dependency Func{IKernel} into parameter lazyKernel of constructor of type HttpApplicationInitializationHttpModule
 1) Request for IHttpModule

Suggestions:
 1) Ensure that you have defined a binding for IntPtr.
 2) If the binding was defined in a module, ensure that the module has been loaded into the kernel.
 3) Ensure you have not accidentally created more than one kernel.
 4) If you are using constructor arguments, ensure that the parameter name matches the constructors parameter name.
 5) If you are using automatic module loading, ensure the search path and filters are correct.
20
VulgarBinary

壁に頭をぶつけすぎて何が起こったのかわかりました。 .NET 4.5で実行されているMVC4のデフォルトのプロジェクトタイプには、更新されたバージョンではなく、元のRCバージョンのSystem.Web.Httpへの参照がありました。

名前空間が欠落していた、オブジェクトが存在していなかった、生活が良くなかった。

解決の手順:

  1. MVC4プロジェクトのSystem.Web.Httpへの参照を削除します
  2. 参照を追加-> System.Web.Http
  3. System.Web.Httpの古いガベージバージョンを機能させるには、入力したすべての回避策を削除します
  4. Ninjectでワイヤリングするための標準プロセスを再適用します。

    ただし、次のエラー:

    例外の詳細:Ninject.ActivationException:IntPtrのアクティブ化エラー一致するバインディングが使用できず、タイプは自己バインドできません。アクティベーションパス:3)タイプFunc {IKernel}のコンストラクターのパラメーターメソッドへの依存関係IntPtrの注入2)タイプHttpApplicationInitializationHttpModuleのコンストラクターのパラメーターlazyKernelへの依存関係Func {IKernel}の注入1)IHttpModuleの要求

    提案:1)IntPtrのバインディングを定義したことを確認してください。 2)バインディングがモジュールで定義されている場合は、モジュールがカーネルにロードされていることを確認してください。 3)誤って複数のカーネルを作成していないことを確認します。 4)コンストラクター引数を使用している場合、パラメーター名がコンストラクターパラメーター名と一致することを確認します。 5)自動モジュールロードを使用している場合は、検索パスとフィルターが正しいことを確認してください。

更新これは、MVCをMVC4ベータからMVC4 RCに更新することで解決しました。

18
VulgarBinary

Pro ASP.NET MVC 3本 をご覧ください。昨夜、このコードをMVC3からMVC4に移植したところ、正しく動作しました。正確には322ページ。

インターフェイスが具体的なアイテムにマッピングされている場所はわかりません。

Bind<ISomething>().To<Something>();

別のコンストラクターを追加し、マッピングを呼び出すメソッドを追加します。

public NinjectDependencyResolver() {
    _kernal = new StandardKernel();
    RegisterServices(_kernel);
}

public static void RegisterServices(IKernel kernel) {
    kernel.Bind<ISomething>().To<Something>();
}

リゾルバは次のようになります。

   public class NinjectDependencyResolver : IDependencyResolver {
    private IKernal _kernel;

    public NinjectDependencyResolver(){
        _kernal = StandardKernal();
        AddBindings();
    }

    public NinjectDependencyResolver(IKernel kernel)
    {
        _kernel = kernel;
    }

    public object GetService(Type serviceType)
     {
         return _kernel.TryGet(serviceType);
     }

     public IEnumerable<object> GetServices(Type serviceType)
     {
        return _kernal.GetAll(serviceType);
     }

    public IBindingToSyntax<T> Bind<T>() {
      return _kernal.Bind<T>();
    }

     public static void RegisterServices(IKernel kernel){
      //Add your bindings here. 
      //This is static as you can use it for WebApi by passing it the IKernel
     }
}

Global.Asx-

Application_Start()

方法

DependencyResolver.SetResolver(new NinjectDependencyResolver());

それでおしまい。


2012年11月14日更新

余談ですが、MVC WebAPIを使用している場合は、nugetから WebApiContrib.IoC.Ninject を使用する必要があります。また、サンプルの "Contact Manager" asp.net.com も確認してください。これはNinjectの実装をクリーンアップするのに役立ちました

5
anAgent

プロジェクトからNinjectWebCommon.csファイルを削除するだけです(App_Startフォルダにあります)。そして、すべてが機能しているはずです。

ソース: http://mlindev.blogspot.com.au/2012/09/how-to-implement-dependency-injection.html

4
1_bug

NuGetパッケージから最新のNinject.MVC3をインストールすると、NinjectWebCommon.csファイルの上に次のコードが見つかります。

[Assembly: WebActivator.PreApplicationStartMethod(typeof(MvcApplication1.App_Start.NinjectWebCommon), "Start")]

[Assembly: WebActivator.ApplicationShutdownMethodAttribute(typeof(MvcApplication1.App_Start.NinjectWebCommon), "Stop")]

この場合、ninjectをglobal.asaxに明示的に登録する必要はありません。

私はMVC 4でNinjectを使用するのに良いコンテンツを見つけました here

1
user2035720

私は同じ問題に遭遇しましたが、以下の変更後に何が修正されたのかよくわかりません

ninject.MVC4をプロジェクトに追加

削除されたNinjectWebCommon.cs(統合は既にglobal.ascx.csファイルに存在するため、生成されたファイル)

0
Naga

DD4Tを使用していますが、同じエラーが発生しました。

すべてのパッケージがnugetパッケージマネージャーによってインストールされていることを確認した後、DLL /参照の一部が欠落していることがわかりました(newtonsoftなど)。

次に、Newtonsoft.Jsonを再インストールし(パッケージを再インストールするには、Nuget Package Manager:Update-Package –reinstall Newtonsoft.Jsonで次のコマンドを使用します)、Tridion Deployer binからnetrtsn.dllを配置すると、このエラーが発生しました-"シーケンスこの質問で与えられたものとまったく同じスタックトレースを持つ要素が含まれていません。

この解決策を提供してくれたNagaに感謝し、NinjectWebCommon.cs(統合は既にglobal.ascx.csファイルに存在するため、生成されたファイル)を削除し、wohooooo !!!!すべてのエラーが解決され、Tridion + MVC4 = DD4Tは正常に動作しています。

0

Nugetを使用して実際のMVC Webサイトプロジェクトによって参照されるプロジェクトにNinject.MVC4をインストールしたときにも、この問題が発生しました。

問題は、参照されたプロジェクトのApp_Startディレクトリに自動的にインストールされたNinjectWebCommon.csファイルが、私のWebサイトプロジェクトにインストールされた(実際の、有用な)ファイルと競合することです。参照プロジェクトからNinjectWebCommon.csファイルを削除すると、エラーが解決します。

0
fordareh

私はNinjectのブートストラップを別のプロジェクトに保持する傾向があります。 _IBindingInSyntax<T>_の.InRequestScope()拡張メソッドを使用するために、Nugetを介してNinject.Web.Commonライブラリを追加しました。残念ながら、このライブラリにはapp_startブートストラップが含まれているため、NinjectWebCommonクラスが重複し、WebActivatorを介して接続されます(上記のプロジェクトに1つ、MVCプロジェクト自体に1つ)。

bootstrapプロジェクトから重複したApp_Startフォルダーを削除しましたが、これで解決しました。