Visual Studio 2012 でプロファイラーを起動すると、Ninject から常に InvalidProgramException を受け取ります。ASP.NET Web アプリケーションでインストルメンテーションを使用しています。開始時に、プロファイラーは VSEnterpriseHelper.axd を介して独自の機能をアプリケーションに追加します。ninject が爆発するのは、このモジュールが初期化されるときです。次のようなエラー メッセージが表示されます。
"The web site could not be configured correctly; getting ASP.NET process information failed. Requesting 'http://localhost:7777/VSEnterpriseHelper.axd' returned an error: The remote server returned an error: (500) Internal Server Error."
500 内部サーバー エラーは、Windows イベント ビューアーで確認できます。
Event code: 3005
Event message: An unhandled exception has occurred.
Event time: 2013-10-31 11:26:11
Event time (UTC): 2013-10-31 10:26:11
Event ID: 8b04f14a2d78430d995bb8d4d6c61728
Event sequence: 4
Event occurrence: 1
Event detail code: 0
Application information:
Application domain: /LM/W3SVC/2/ROOT-1-130276887605936349
Trust level: Full
Application Virtual Path: /
Application Path: C:\TFS\MyCompany Projects\Main\www\
Machine name: JEGO
Process information:
Process ID: 7876
Process name: w3wp.exe
Account name: MyCompany\august
Exception information:
Exception type: InvalidProgramException
Exception message: Common Language Runtime detected an invalid program.
at System.Runtime.CompilerServices.RuntimeHelpers._CompileMethod(IRuntimeMethodInfo method)
at System.Reflection.Emit.DynamicMethod.CreateDelegate(Type delegateType)
at Ninject.Injection.DynamicMethodInjectorFactory.Create(ConstructorInfo constructor)
at Ninject.Planning.Strategies.ConstructorReflectionStrategy.Execute(IPlan plan)
at Ninject.Infrastructure.Language.ExtensionsForIEnumerableOfT.Map[T](IEnumerable`1 series, Action`1 action)
at Ninject.Planning.Planner.CreateNewPlan(Type type)
at Ninject.Planning.Planner.GetPlan(Type type)
at Ninject.Activation.Context.Resolve()
at System.Linq.Enumerable.WhereSelectEnumerableIterator`2.MoveNext()
at System.Linq.Enumerable.SingleOrDefault[TSource](IEnumerable`1 source)
at System.Linq.Enumerable.WhereSelectArrayIterator`2.MoveNext()
at System.Linq.Buffer`1..ctor(IEnumerable`1 source)
at System.Linq.Enumerable.ToArray[TSource](IEnumerable`1 source)
at Ninject.Activation.Providers.StandardProvider.Create(IContext context)
at Ninject.Activation.Context.Resolve()
at System.Linq.Enumerable.WhereSelectListIterator`2.MoveNext()
at System.Linq.Enumerable.<CastIterator>d__b1`1.MoveNext()
at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)
at Ninject.Web.Common.NinjectHttpModule.Init(HttpApplication context)
at System.Web.HttpApplication.RegisterEventSubscriptionsWithIIS(IntPtr appContext, HttpContext context, MethodInfo[] handlers)
at System.Web.HttpApplication.InitSpecial(HttpApplicationState state, MethodInfo[] handlers, IntPtr appContext, HttpContext context)
at System.Web.HttpApplicationFactory.GetSpecialApplicationInstance(IntPtr appContext, HttpContext context)
at System.Web.Hosting.PipelineRuntime.InitializeApplication(IntPtr appContext)
Request information:
Request URL: http://localhost:7777/VSEnterpriseHelper.axd
Request path: /VSEnterpriseHelper.axd
User host address: ::1
User:
Is authenticated: False
Authentication Type:
Thread account name: MyCompany\august
Thread information:
Thread ID: 7
Thread account name: MyCompany\august
Is impersonating: False
Stack trace: at System.Runtime.CompilerServices.RuntimeHelpers._CompileMethod(IRuntimeMethodInfo method)
at System.Reflection.Emit.DynamicMethod.CreateDelegate(Type delegateType)
at Ninject.Injection.DynamicMethodInjectorFactory.Create(ConstructorInfo constructor)
at Ninject.Planning.Strategies.ConstructorReflectionStrategy.Execute(IPlan plan)
at Ninject.Infrastructure.Language.ExtensionsForIEnumerableOfT.Map[T](IEnumerable`1 series, Action`1 action)
at Ninject.Planning.Planner.CreateNewPlan(Type type)
at Ninject.Planning.Planner.GetPlan(Type type)
at Ninject.Activation.Context.Resolve()
at System.Linq.Enumerable.WhereSelectEnumerableIterator`2.MoveNext()
at System.Linq.Enumerable.SingleOrDefault[TSource](IEnumerable`1 source)
at System.Linq.Enumerable.WhereSelectArrayIterator`2.MoveNext()
at System.Linq.Buffer`1..ctor(IEnumerable`1 source)
at System.Linq.Enumerable.ToArray[TSource](IEnumerable`1 source)
at Ninject.Activation.Providers.StandardProvider.Create(IContext context)
at Ninject.Activation.Context.Resolve()
at System.Linq.Enumerable.WhereSelectListIterator`2.MoveNext()
at System.Linq.Enumerable.<CastIterator>d__b1`1.MoveNext()
at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)
at Ninject.Web.Common.NinjectHttpModule.Init(HttpApplication context)
at System.Web.HttpApplication.RegisterEventSubscriptionsWithIIS(IntPtr appContext, HttpContext context, MethodInfo[] handlers)
at System.Web.HttpApplication.InitSpecial(HttpApplicationState state, MethodInfo[] handlers, IntPtr appContext, HttpContext context)
at System.Web.HttpApplicationFactory.GetSpecialApplicationInstance(IntPtr appContext, HttpContext context)
at System.Web.Hosting.PipelineRuntime.InitializeApplication(IntPtr appContext)
上記のスタック トレースでは、コンストラクターのパラメーターは次のとおりです。
Ninject.Injection.DynamicMethodInjectorFactory.Create(ConstructorInfo constructor)
System.Func< IKernel > のコンストラクターを保持します。
そして、これは私たちが使用するスタートアップ構成です (Ninject.Web.Common):
using System;
using System.Collections.Generic;
using System.Web;
using System.Web.Http;
using MyCompany.Classlib.Misc;
using Microsoft.Web.Infrastructure.DynamicModuleHelper;
using Ninject;
using Ninject.Web.Common;
using MyCompany;
[assembly: PreApplicationStartMethod( typeof( NinjectWebCommon ), "Start" )]
namespace MyCompany
{
public static class NinjectWebCommon
{
private static readonly Bootstrapper __bootstrapper = new Bootstrapper();
/// <summary>
/// Starts the application
/// </summary>
public static void Start()
{
DynamicModuleUtility.RegisterModule( typeof( Ninject.Web.NinjectHttpModule ) );
DynamicModuleUtility.RegisterModule( typeof( OnePerRequestHttpModule ) );
DynamicModuleUtility.RegisterModule( typeof( NinjectHttpModule ) );
__bootstrapper.Initialize( CreateKernel );
}
/// <summary>
/// Stops the application.
/// </summary>
public static void Stop()
{
__bootstrapper.ShutDown();
}
/// <summary>
/// Creates the kernel that will manage your application.
/// </summary>
/// <returns>The created kernel.</returns>
private static IKernel CreateKernel()
{
var kernel = new StandardKernel();
kernel.Bind<Func<IKernel>>().ToMethod( ctx => () => new Bootstrapper().Kernel );
kernel.Bind<IHttpModule>().To<HttpApplicationInitializationHttpModule>();
RegisterServices( kernel );
// Setup Ninject with DependencyResolver. Enables constructor injection in controller classes in the IntegrationApi (WebAPI).
GlobalConfiguration.Configuration.DependencyResolver = new NinjectDependencyResolver( kernel );
return kernel;
}
/// <summary>
/// Load your modules or register your services here!
/// </summary>
/// <param name="kernel">The kernel.</param>
private static void RegisterServices( IKernel kernel )
{
Kernel.Initialize( kernel );
Module.Initialize( kernel );
}
}
}
注目に値するのは、行が次の場合です。
var kernel = new StandardKernel();
次のものに置き換えられます。
var kernel = new StandardKernel( new NinjectSettings { UseReflectionBasedInjection = true } );
すべてがうまく機能します。しかし、コード生成がより高速でデフォルトであることを考えると、これは正しい解決策とは思えません。
より高速なコード生成ベースのインジェクション メソッドを引き続き使用できるように InvalidProgramException を修正する方法を知っている人はいますか?