我们正在构建一个包含UI和API的网站,这两个网站都托管在单个ASP.NET MVC项目中(“常用”MVC + MVC WebApi在一个引擎盖下)。我们使用SimpleInjector(最新版本,2.8截至目前)进行依赖注入。我们有单一的组合根类来构建UI和API部分的容器。
最近(几周前注意到)我们在尝试访问QA中的任何API方法时都收到连接重置错误(ERR_CONNECTION_RESET
)。 UAT中的相同代码工作得很好。
在本地,如果在IIS下运行,则StackOverflowException
的相同代码会出错,但如果我们在附加调试器的情况下运行它,则在IIS Express和IIS下运行正常。
我们当前的代码在异常发生后附加到iis工作进程时给出以下堆栈跟踪:
SimpleInjector.Compiled!DynamicInstanceProducer3.GetInstance(object[] constants)
SimpleInjector.dll!SimpleInjector.CompilationHelpers.CompileInDynamicAssemblyAsClosure<System.__Canon>.AnonymousMethod__1a()
SimpleInjector.dll!SimpleInjector.InstanceProducer.GetInstance()
SimpleInjector.dll!SimpleInjector.Container.GetInstance(System.Type serviceType)
System.Web.Http.dll!System.Web.Http.Dispatcher.DefaultHttpControllerActivator.GetInstanceOrActivator(System.Net.Http.HttpRequestMessage request, System.Type controllerType, out System.Func<System.Web.Http.Controllers.IHttpController> activator)
System.Web.Http.dll!System.Web.Http.Dispatcher.DefaultHttpControllerActivator.Create(System.Net.Http.HttpRequestMessage request, System.Web.Http.Controllers.HttpControllerDescriptor controllerDescriptor, System.Type controllerType)
System.Web.Http.dll!System.Web.Http.Controllers.HttpControllerDescriptor.CreateController(System.Net.Http.HttpRequestMessage request)
System.Web.Http.dll!System.Web.Http.Dispatcher.HttpControllerDispatcher.SendAsync()
mscorlib.dll!System.Runtime.CompilerServices.AsyncMethodBuilderCore.Start<System.Web.Http.Dispatcher.HttpControllerDispatcher.SendAsync>(ref System.Web.Http.Dispatcher.HttpControllerDispatcher.SendAsync stateMachine)
System.Web.Http.dll!System.Web.Http.Dispatcher.HttpControllerDispatcher.SendAsync(System.Net.Http.HttpRequestMessage request, System.Threading.CancellationToken cancellationToken)
System.Net.Http.dll!System.Net.Http.HttpMessageInvoker.SendAsync(System.Net.Http.HttpRequestMessage request, System.Threading.CancellationToken cancellationToken)
System.Web.Http.dll!System.Web.Http.Dispatcher.HttpRoutingDispatcher.SendAsync(System.Net.Http.HttpRequestMessage request, System.Threading.CancellationToken cancellationToken)
System.Web.Http.dll!System.Web.Http.HttpServer.SendAsync()
mscorlib.dll!System.Runtime.CompilerServices.AsyncMethodBuilderCore.Start<System.Web.Http.HttpServer.SendAsync>(ref System.Web.Http.HttpServer.SendAsync stateMachine)
System.Web.Http.dll!System.Web.Http.HttpServer.SendAsync(System.Net.Http.HttpRequestMessage request, System.Threading.CancellationToken cancellationToken)
System.Net.Http.dll!System.Net.Http.HttpMessageInvoker.SendAsync(System.Net.Http.HttpRequestMessage request, System.Threading.CancellationToken cancellationToken)
System.Web.Http.WebHost.dll!System.Web.Http.WebHost.HttpControllerHandler.ProcessRequestAsyncCore()
mscorlib.dll!System.Runtime.CompilerServices.AsyncMethodBuilderCore.Start<System.Web.Http.WebHost.HttpControllerHandler.ProcessRequestAsyncCore>(ref System.Web.Http.WebHost.HttpControllerHandler.ProcessRequestAsyncCore stateMachine)
System.Web.Http.WebHost.dll!System.Web.Http.WebHost.HttpControllerHandler.ProcessRequestAsyncCore(System.Web.HttpContextBase contextBase)
System.Web.dll!System.Web.TaskAsyncHelper.BeginTask(System.Func<System.Threading.Tasks.Task> taskFunc, System.AsyncCallback callback, object state)
System.Web.dll!System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
System.Web.dll!System.Web.HttpApplication.ExecuteStep(System.Web.HttpApplication.IExecutionStep step, ref bool completedSynchronously)
System.Web.dll!System.Web.HttpApplication.PipelineStepManager.ResumeSteps(System.Exception error)
System.Web.dll!System.Web.HttpApplication.BeginProcessRequestNotification(System.Web.HttpContext context, System.AsyncCallback cb)
System.Web.dll!System.Web.HttpRuntime.ProcessRequestNotificationPrivate(System.Web.Hosting.IIS7WorkerRequest wr, System.Web.HttpContext context)
System.Web.dll!System.Web.Hosting.PipelineRuntime.ProcessRequestNotificationHelper(System.IntPtr rootedObjectsPointer, System.IntPtr nativeRequestContext, System.IntPtr moduleData, int flags)
System.Web.dll!System.Web.Hosting.PipelineRuntime.ProcessRequestNotification(System.IntPtr rootedObjectsPointer, System.IntPtr nativeRequestContext, System.IntPtr moduleData, int flags)
[Native to Managed Transition]
[Managed to Native Transition]
System.Web.dll!System.Web.Hosting.PipelineRuntime.ProcessRequestNotificationHelper(System.IntPtr rootedObjectsPointer, System.IntPtr nativeRequestContext, System.IntPtr moduleData, int flags)
System.Web.dll!System.Web.Hosting.PipelineRuntime.ProcessRequestNotification(System.IntPtr rootedObjectsPointer, System.IntPtr nativeRequestContext, System.IntPtr moduleData, int flags)
[AppDomain Transition]
即,在我们的代码中看起来没什么不好的。
当我们采用一些旧代码(例如,当前正在生产中并且工作正常)时,我们也有StackOverflowException
,但是我们的EntityFramework DB上下文的静态构造函数(代码优先)在线
Database.SetInitializer(new MigrateDatabaseToLatestVersion<MyContextType, Configuration>());
有趣的是,它不再建议使用旧代码附加到进程,因此我无法提供堆栈跟踪 - 如果我设法抓住它,我将更新问题。
请注意,通常的MVC仍然正常工作(使用相同的Composition Root类,WebApi和MVC创建模式略有自然差异)。
我可以提供更多的代码片段,如果它是合理的,但是项目非常大,所以我不确定小片段会对此有所帮助。
任何想法可能是什么?是不是因为依赖的数量?
UPDATE:在依赖于其他四个服务的其中一个服务之后,我没有出现问题我从构造函数中删除了依赖项,在那里注入了容器,并在构造函数中手动解析了依赖项。即,它是:
public MyDependentService(IDependency1 dependency1, IDependency2 dependency2, IDependency3 dependency3, IDependency4 dependency4)
{
this.dependency1 = dependency1;
this.dependency2 = dependency2;
this.dependency3 = dependency3;
this.dependency4 = dependency4;
}
它变成了
public MyDependentService(Container container)
{
this.dependency1 = container.GetInstance<IDependency1>();
this.dependency2 = container.GetInstance<IDependency2>();
this.dependency3 = container.GetInstance<IDependency3>();
this.dependency4 = container.GetInstance<IDependency4>();
}
所以现在一切正常,但当然这不是处理依赖关系的正确方法。这实际上不再是IoC。发生了什么事?