2017-06-23 218 views
1

我們在Ninject的WebAPI 2項目中成功使用Microsoft ASP.Net Webhooks(特別是Stripe one)。最近我們遷移到SimpleInjector,而其他一切進展順利,我們無法讓這個webhook處理器工作。它不斷拋出以下異常:System.MissingMethodException: 'No parameterless constructor defined for this object.'SimpleInjector和Microsoft Webhook ASP.Net Webhooks

相關的堆棧跟蹤是:

mscorlib.dll!System.RuntimeType.CreateInstanceSlow(bool publicOnly, bool skipCheckThis, bool fillCache, ref System.Threading.StackCrawlMark stackMark) Unknown 
mscorlib.dll!System.Activator.CreateInstance(System.Type type, bool nonPublic) Unknown 
mscorlib.dll!System.Activator.CreateInstance(System.Type type) Unknown 
Microsoft.AspNet.WebHooks.Common.dll!Microsoft.AspNet.WebHooks.Utilities.TypeUtilities.GetInstances<Microsoft.AspNet.WebHooks.IWebHookHandler>(System.Collections.Generic.IEnumerable<System.Reflection.Assembly> assemblies, System.Func<System.Type, bool> predicate) Unknown 
Microsoft.AspNet.WebHooks.Receivers.dll!Microsoft.AspNet.WebHooks.ReceiverServices.GetHandlers() Unknown 
Microsoft.AspNet.WebHooks.Receivers.dll!Microsoft.AspNet.WebHooks.DependencyScopeExtensions.GetHandlers(System.Web.Http.Dependencies.IDependencyScope services = {SimpleInjector.Integration.WebApi.SimpleInjectorWebApiDependencyResolver}) Unknown 
Microsoft.AspNet.WebHooks.Receivers.dll!Microsoft.AspNet.WebHooks.WebHookReceiver.ExecuteWebHookAsync(string id = "", System.Web.Http.Controllers.HttpRequestContext context = {System.Web.Http.WebHost.WebHostHttpRequestContext}, System.Net.Http.HttpRequestMessage request = {System.Net.Http.HttpRequestMessage}, System.Collections.Generic.IEnumerable<string> actions = {string[1]}, object data = {Newtonsoft.Json.Linq.JObject}) Unknown 
mscorlib.dll!System.Runtime.CompilerServices.AsyncTaskMethodBuilder<System.__Canon>.Start<Microsoft.AspNet.WebHooks.WebHookReceiver.<ExecuteWebHookAsync>d__22>(ref Microsoft.AspNet.WebHooks.WebHookReceiver.<ExecuteWebHookAsync>d__22 stateMachine) Unknown 
Microsoft.AspNet.WebHooks.Receivers.dll!Microsoft.AspNet.WebHooks.WebHookReceiver.ExecuteWebHookAsync(string id, System.Web.Http.Controllers.HttpRequestContext context, System.Net.Http.HttpRequestMessage request, System.Collections.Generic.IEnumerable<string> actions, object data) Unknown 
Microsoft.AspNet.WebHooks.Receivers.Stripe.dll!Microsoft.AspNet.WebHooks.StripeWebHookReceiver.ReceiveAsync(string id = "", System.Web.Http.Controllers.HttpRequestContext context = {System.Web.Http.WebHost.WebHostHttpRequestContext}, System.Net.Http.HttpRequestMessage request = {System.Net.Http.HttpRequestMessage}) Unknown 
mscorlib.dll!System.Runtime.CompilerServices.AsyncTaskMethodBuilder<System.__Canon>.Start<Microsoft.AspNet.WebHooks.StripeWebHookReceiver.<ReceiveAsync>d__15>(ref Microsoft.AspNet.WebHooks.StripeWebHookReceiver.<ReceiveAsync>d__15 stateMachine) Unknown 
Microsoft.AspNet.WebHooks.Receivers.Stripe.dll!Microsoft.AspNet.WebHooks.StripeWebHookReceiver.ReceiveAsync(string id, System.Web.Http.Controllers.HttpRequestContext context, System.Net.Http.HttpRequestMessage request) Unknown 
Microsoft.AspNet.WebHooks.Receivers.dll!Microsoft.AspNet.WebHooks.Controllers.WebHookReceiversController.ProcessWebHook(string webHookReceiver = "stripe", string id = "") Unknown 
mscorlib.dll!System.Runtime.CompilerServices.AsyncTaskMethodBuilder<System.__Canon>.Start<Microsoft.AspNet.WebHooks.Controllers.WebHookReceiversController.<ProcessWebHook>d__3>(ref Microsoft.AspNet.WebHooks.Controllers.WebHookReceiversController.<ProcessWebHook>d__3 stateMachine) Unknown 
Microsoft.AspNet.WebHooks.Receivers.dll!Microsoft.AspNet.WebHooks.Controllers.WebHookReceiversController.ProcessWebHook(string webHookReceiver, string id) Unknown 
[Lightweight Function] 
System.Web.Http.dll!System.Web.Http.Controllers.ReflectedHttpActionDescriptor.ActionExecutor.GetExecutor.AnonymousMethod__8(object instance, object[] methodParameters) Unknown 
System.Web.Http.dll!System.Web.Http.Controllers.ReflectedHttpActionDescriptor.ExecuteAsync(System.Web.Http.Controllers.HttpControllerContext controllerContext, System.Collections.Generic.IDictionary<string, object> arguments, System.Threading.CancellationToken cancellationToken) Unknown 
System.Web.Http.dll!System.Web.Http.Controllers.ApiControllerActionInvoker.InvokeActionAsyncCore(System.Web.Http.Controllers.HttpActionContext actionContext = {System.Web.Http.Controllers.HttpActionContext}, System.Threading.CancellationToken cancellationToken = IsCancellationRequested = false) Unknown 
mscorlib.dll!System.Runtime.CompilerServices.AsyncTaskMethodBuilder<System.__Canon>.Start<System.Web.Http.Controllers.ApiControllerActionInvoker.<InvokeActionAsyncCore>d__0>(ref System.Web.Http.Controllers.ApiControllerActionInvoker.<InvokeActionAsyncCore>d__0 stateMachine) Unknown 
System.Web.Http.dll!System.Web.Http.Controllers.ApiControllerActionInvoker.InvokeActionAsyncCore(System.Web.Http.Controllers.HttpActionContext actionContext, System.Threading.CancellationToken cancellationToken) Unknown 
System.Web.Http.dll!System.Web.Http.Controllers.ApiControllerActionInvoker.InvokeActionAsync(System.Web.Http.Controllers.HttpActionContext actionContext, System.Threading.CancellationToken cancellationToken) Unknown 
System.Web.Http.dll!System.Web.Http.Controllers.ActionFilterResult.ExecuteAsync(System.Threading.CancellationToken cancellationToken = IsCancellationRequested = false) Unknown 
mscorlib.dll!System.Runtime.CompilerServices.AsyncTaskMethodBuilder<System.__Canon>.Start<System.Web.Http.Controllers.ActionFilterResult.<ExecuteAsync>d__2>(ref System.Web.Http.Controllers.ActionFilterResult.<ExecuteAsync>d__2 stateMachine) Unknown 
System.Web.Http.dll!System.Web.Http.Controllers.ActionFilterResult.ExecuteAsync(System.Threading.CancellationToken cancellationToken) Unknown 
System.Web.Http.dll!System.Web.Http.ApiController.ExecuteAsync(System.Web.Http.Controllers.HttpControllerContext controllerContext, System.Threading.CancellationToken cancellationToken) Unknown 
System.Web.Http.dll!System.Web.Http.Dispatcher.HttpControllerDispatcher.SendAsync(System.Net.Http.HttpRequestMessage request = {System.Net.Http.HttpRequestMessage}, System.Threading.CancellationToken cancellationToken = IsCancellationRequested = false) Unknown 
mscorlib.dll!System.Runtime.CompilerServices.AsyncTaskMethodBuilder<System.__Canon>.Start<System.Web.Http.Dispatcher.HttpControllerDispatcher.<SendAsync>d__1>(ref System.Web.Http.Dispatcher.HttpControllerDispatcher.<SendAsync>d__1 stateMachine) Unknown 
System.Web.Http.dll!System.Web.Http.Dispatcher.HttpControllerDispatcher.SendAsync(System.Net.Http.HttpRequestMessage request, System.Threading.CancellationToken cancellationToken) Unknown 
System.Net.Http.dll!System.Net.Http.HttpMessageInvoker.SendAsync(System.Net.Http.HttpRequestMessage request, System.Threading.CancellationToken cancellationToken) Unknown 
System.Web.Http.dll!System.Web.Http.Dispatcher.HttpRoutingDispatcher.SendAsync(System.Net.Http.HttpRequestMessage request, System.Threading.CancellationToken cancellationToken) Unknown 
System.Net.Http.dll!System.Net.Http.DelegatingHandler.SendAsync(System.Net.Http.HttpRequestMessage request, System.Threading.CancellationToken cancellationToken) Unknown 
System.Web.Http.Cors.dll!System.Web.Http.Cors.CorsMessageHandler.SendAsync(System.Net.Http.HttpRequestMessage request = {System.Net.Http.HttpRequestMessage}, System.Threading.CancellationToken cancellationToken = IsCancellationRequested = false) Unknown 
mscorlib.dll!System.Runtime.CompilerServices.AsyncTaskMethodBuilder<System.__Canon>.Start<System.Web.Http.Cors.CorsMessageHandler.<SendAsync>d__0>(ref System.Web.Http.Cors.CorsMessageHandler.<SendAsync>d__0 stateMachine) Unknown 
System.Web.Http.Cors.dll!System.Web.Http.Cors.CorsMessageHandler.SendAsync(System.Net.Http.HttpRequestMessage request, System.Threading.CancellationToken cancellationToken) Unknown 
System.Net.Http.dll!System.Net.Http.DelegatingHandler.SendAsync(System.Net.Http.HttpRequestMessage request, System.Threading.CancellationToken cancellationToken) Unknown 
System.Web.Http.dll!System.Web.Http.HttpServer.SendAsync(System.Net.Http.HttpRequestMessage request = {System.Net.Http.HttpRequestMessage}, System.Threading.CancellationToken cancellationToken = IsCancellationRequested = false) Unknown 
mscorlib.dll!System.Runtime.CompilerServices.AsyncTaskMethodBuilder<System.__Canon>.Start<System.Web.Http.HttpServer.<SendAsync>d__0>(ref System.Web.Http.HttpServer.<SendAsync>d__0 stateMachine) Unknown 
System.Web.Http.dll!System.Web.Http.HttpServer.SendAsync(System.Net.Http.HttpRequestMessage request, System.Threading.CancellationToken cancellationToken) Unknown 
System.Net.Http.dll!System.Net.Http.HttpMessageInvoker.SendAsync(System.Net.Http.HttpRequestMessage request, System.Threading.CancellationToken cancellationToken) Unknown 
System.Web.Http.WebHost.dll!System.Web.Http.WebHost.HttpControllerHandler.ProcessRequestAsyncCore(System.Web.HttpContextBase contextBase = {System.Web.HttpContextWrapper}) Unknown 
mscorlib.dll!System.Runtime.CompilerServices.AsyncTaskMethodBuilder.Start<System.Web.Http.WebHost.HttpControllerHandler.<ProcessRequestAsyncCore>d__0>(ref System.Web.Http.WebHost.HttpControllerHandler.<ProcessRequestAsyncCore>d__0 stateMachine) Unknown 
System.Web.Http.WebHost.dll!System.Web.Http.WebHost.HttpControllerHandler.ProcessRequestAsyncCore(System.Web.HttpContextBase contextBase) Unknown 
System.Web.dll!System.Web.TaskAsyncHelper.BeginTask(System.Func<System.Threading.Tasks.Task> taskFunc, System.AsyncCallback callback, object state = null) Unknown 
System.Web.dll!System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() Unknown 
System.Web.dll!System.Web.HttpApplication.ExecuteStep(System.Web.HttpApplication.IExecutionStep step = {System.Web.HttpApplication.CallHandlerExecutionStep}, ref bool completedSynchronously = false) Unknown 
System.Web.dll!System.Web.HttpApplication.PipelineStepManager.ResumeSteps(System.Exception error) Unknown 
System.Web.dll!System.Web.HttpApplication.BeginProcessRequestNotification(System.Web.HttpContext context, System.AsyncCallback cb) Unknown 
System.Web.dll!System.Web.HttpRuntime.ProcessRequestNotificationPrivate(System.Web.Hosting.IIS7WorkerRequest wr = {System.Web.Hosting.IIS7WorkerRequest}, System.Web.HttpContext context = {System.Web.HttpContext}) Unknown 
System.Web.dll!System.Web.Hosting.PipelineRuntime.ProcessRequestNotificationHelper(System.IntPtr rootedObjectsPointer, System.IntPtr nativeRequestContext = 0x000002226c0521f0, System.IntPtr moduleData, int flags) Unknown 
System.Web.dll!System.Web.Hosting.PipelineRuntime.ProcessRequestNotification(System.IntPtr rootedObjectsPointer, System.IntPtr nativeRequestContext, System.IntPtr moduleData, int flags) Unknown 
[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) Unknown 
System.Web.dll!System.Web.Hosting.PipelineRuntime.ProcessRequestNotification(System.IntPtr rootedObjectsPointer, System.IntPtr nativeRequestContext, System.IntPtr moduleData, int flags) Unknown 
[AppDomain Transition] 

而且

System.MissingMethodException: No parameterless constructor defined for this object. 
at System.RuntimeTypeHandle.CreateInstance(RuntimeType type, Boolean publicOnly, Boolean noCheck, Boolean& canBeCached, RuntimeMethodHandleInternal& ctor, Boolean& bNeedSecurityCheck) 
at System.RuntimeType.CreateInstanceSlow(Boolean publicOnly, Boolean skipCheckThis, Boolean fillCache, StackCrawlMark& stackMark) 
at System.Activator.CreateInstance(Type type, Boolean nonPublic) 
at System.Activator.CreateInstance(Type type) 
at Microsoft.AspNet.WebHooks.Utilities.TypeUtilities.GetInstances[T](IEnumerable`1 assemblies, Func`2 predicate) 
at Microsoft.AspNet.WebHooks.ReceiverServices.GetHandlers() 
at Microsoft.AspNet.WebHooks.DependencyScopeExtensions.GetHandlers(IDependencyScope services) 
at Microsoft.AspNet.WebHooks.WebHookReceiver.<ExecuteWebHookAsync>d__22.MoveNext() 
--- End of stack trace from previous location where exception was thrown --- 
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) 
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) 
at Microsoft.AspNet.WebHooks.StripeWebHookReceiver.<ReceiveAsync>d__15.MoveNext() 
--- End of stack trace from previous location where exception was thrown --- 
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) 
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) 
at Microsoft.AspNet.WebHooks.Controllers.WebHookReceiversController.<ProcessWebHook>d__3.MoveNext() 
--- End of stack trace from previous location where exception was thrown --- 
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) 
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) 
at System.Threading.Tasks.TaskHelpersExtensions.<CastToObject>d__3`1.MoveNext() 
--- End of stack trace from previous location where exception was thrown --- 
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) 
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) 
at System.Web.Http.Controllers.ApiControllerActionInvoker.<InvokeActionAsyncCore>d__0.MoveNext() 
--- End of stack trace from previous location where exception was thrown --- 
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) 
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) 
at System.Web.Http.Controllers.ActionFilterResult.<ExecuteAsync>d__2.MoveNext() 
--- End of stack trace from previous location where exception was thrown --- 
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) 
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) 
at System.Web.Http.Dispatcher.HttpControllerDispatcher.<SendAsync>d__1.MoveNext() 

我們Global.asax的是這樣的:

var container = new Container(); 
container.Options.DefaultScopedLifestyle = new AsyncScopedLifestyle(); 
container.Options.PropertySelectionBehavior = new 
InjectPropertySelectionBehavior(); 

// Register our stuff 

container.RegisterMvcControllers(Assembly.GetExecutingAssembly()); 
container.RegisterWebApiControllers(GlobalConfiguration.Configuration); 

container.Verify(); 

GlobalConfiguration.Configuration.DependencyResolver = new 
SimpleInjectorWebApiDependencyResolver(container); 
DependencyResolver.SetResolver(new SimpleInjectorDependencyResolver(container)); 

我們」重新註冊這樣的WebHook處理程序:

container.Register<IWebHookHandler, StripeWebhookHandler>(Lifestyle.Singleton);

有沒有人得到這個與SimpleInjector一起工作?或者有什麼想法可能是錯誤的?

+0

您爲什麼認爲這與簡單注射器有關?那麼堆棧軌跡顯示沒有涉及簡單注入器的跡象。 – Steven

+0

這是一個很好的觀點,仔細觀察堆棧軌跡,這不是很有幫助。我懷疑它是SimpleInjector的原因是因爲它與Ninject一起工作得很好,而且這是唯一被改變的東西。我應該在上面注意到,StripeWebhookHandler類是我們定義的繼承WebhookHandler(他們)的類,並且具有依賴關係的構造函數。 – mscrivo

+1

堆棧跟蹤似乎意味着Web鉤子通過對其使用Activator.CreateInstance來解析IWebHookHandler,當類型是接口(Web鉤子拋出錯誤的異常消息)時,它顯然會失敗。您是否可能錯過了將IWebHookHandler解決方案重定向到Simple Injector的集成點? Ninject是否有這樣的集成包? – Steven

回答

1

解決方案:

IWebhookHandler需要註冊爲一個集合,所以這樣做:的

container.AppendToCollection(typeof(IWebHookHandler), typeof(StripeWebhookHandler));

代替:

container.Register<IWebHookHandler, StripeWebhookHandler>(Lifestyle.Singleton);

是的伎倆!

我想通了這一點踩踏到Microsoft網絡掛接組裝和SimpleInjector兩者的來源,發現當網絡掛接裝配要求IWebhookHandler類型的所有實例,SimpleInjector在其GetServices執行試圖找到所有IEnumerable<IWebhookHandler>,而不是和所以沒有任何東西。

0

嘗試解析具有參數構造函數的依賴項時會引發這些類型的異常,但一個或多個參數尚未註冊並因此無法解析,從而導致回退到無參數構造函數某些情況不存在。

確認您已註冊WebHooks工作所需的所有組件。