20

それで、いろいろいじった後、最終的に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.
     }
}

ここでの洞察は大歓迎です。DI フレームワークを .NET 4.5 で実行されている最新の MVC4 RC に接続するのにすでに多くの時間を費やしてきましたが、まったく機能しないことに対する許容レベルに達しました..

編集#1 githubで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 の経験が豊富な方にとってより簡単になることを願っています。

編集 #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.
4

8 に答える 8

18

あまりにも長い間壁に頭をぶつけた後、何が起こっているのかを理解しました。.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 Beta から MVC4 RC に更新することで解決されました。

于 2012-07-13T13:53:22.237 に答える
5

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 を使用することをお勧めします。また、サンプルasp.net.comで「連絡先マネージャー」を確認してください。これは、Ninject の実装をクリーンアップするのに役立ちました

于 2012-07-13T13:09:53.987 に答える
1

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を使用することに関する良いコンテンツを見つけました

于 2013-02-02T17:55:56.543 に答える
0

以下の変更後に何が修正されたのかよくわからない同じ問題に遭遇しました

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

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

于 2014-04-28T20:41:04.160 に答える
0

私は自分の Ninject ブートストラップを別のプロジェクトに保持する傾向があります。.InRequestScope()の拡張メソッドを使用するために、 Ninject.Web.CommonライブラリIBindingInSyntax<T>を Nuget 経由で追加しました。悲しいかな、このライブラリには app_start ブートストラップが含まれているため、NinjectWebCommon クラスが重複し、WebActivator を介して添付ファイルが作成されます (上記のプロジェクトに 1 つ、MVC プロジェクト自体に 1 つ)。

ブートストラップ プロジェクトから重複した App_Start フォルダーを削除したところ、これで解決しました。

于 2013-11-13T23:11:25.150 に答える
0

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

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

于 2014-08-15T22:06:42.153 に答える
0

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

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

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

この解決策を提供してくれた Naga に感謝します。すべてのエラーが解決され、Tridion + MVC4 = DD4T は正常に動作しています。

于 2014-06-12T06:39:03.743 に答える