asp.net – 使用Web Api,SignalR,MVC和OWIN的Ninject
我在我的Web应用程序中使用了Ninject DI,其中包含来自Asp.Net堆栈(MVC,Web Api 2,SignalR)的一堆技术.
我已设法通过以下方法使DI适用于所有正在使用的技术: public static class NinjectWebCommon { private static readonly Bootstrapper bootstrapper = new Bootstrapper(); /// <summary> /// Starts the application /// </summary> public static void Start() { 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> internal static IKernel CreateKernel() { var kernel = new StandardKernel(); kernel.Bind<Func<IKernel>>().ToMethod(ctx => () => new Bootstrapper().Kernel); kernel.Bind<IHttpModule>().To<HttpApplicationInitializationHttpModule>(); RegisterServices(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) { GlobalHost.DependencyResolver = new Microsoft.AspNet.SignalR.Ninject.NinjectDependencyResolver(kernel); DependencyResolver.SetResolver(new NinjectDependencyResolver(kernel)); // Binding services here } } 到现在为止还挺好. 所有这一切都在使用Global.asax初始化的Web Api. 现在我正在切换到OWIN管道.所以我删除了GlobalConfiguration.Configure(WebApiConfig.Register);来自Global.asax并补充说 HttpConfiguration config = new HttpConfiguration(); WebApiConfig.Register(config); app.UseWebApi(config); 到我的OwinStartup课程. DI用于Web Api停止工作. 我开始寻找合适的解决方案,并找到了Ninject.Web.WebApi.OwinHost包.因此,为了让所有技术都有一个内核解析依赖关系,我做了以下更改: 在OwinStartup: app.UseNinjectMiddleware(NinjectWebCommon.CreateKernel); app.UseNinjectWebApi(config); 在NinjectWebCommon中: //[assembly: WebActivatorEx.PreApplicationStartMethod(typeof(App.TradingServer.ConfiguratorApp.App_Start.NinjectWebCommon),"Start")] //[assembly: WebActivatorEx.ApplicationShutdownMethodAttribute(typeof(App.TradingServer.ConfiguratorApp.App_Start.NinjectWebCommon),"Stop")] 这些行被禁用以避免两次初始化内核. 这个固定DI用于Web Api,但不适用于SignalR.当客户端尝试连接到集线器时,我得到以下异常: System.NullReferenceException: Object reference not set to an instance of an object. at Microsoft.AspNet.SignalR.PersistentConnection.ProcessNegotiationRequest(HostContext context) at Microsoft.AspNet.SignalR.PersistentConnection.ProcessRequest(HostContext context) at Microsoft.AspNet.SignalR.Hubs.HubDispatcher.ProcessRequest(HostContext context) at Microsoft.AspNet.SignalR.PersistentConnection.ProcessRequest(IDictionary`2 environment) at Microsoft.AspNet.SignalR.Owin.Middleware.HubDispatcherMiddleware.Invoke(IOwinContext context) at Microsoft.Owin.Infrastructure.OwinMiddlewareTransition.Invoke(IDictionary`2 environment) at Microsoft.Owin.Mapping.MapMiddleware.<Invoke>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.Runtime.CompilerServices.TaskAwaiter.GetResult() at System.Web.Http.Owin.HttpMessageHandlerAdapter.<InvokeCore>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.Runtime.CompilerServices.TaskAwaiter.GetResult() at Ninject.Web.Common.OwinHost.OwinBootstrapper.<Execute>d__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.Runtime.CompilerServices.TaskAwaiter.GetResult() at Microsoft.Owin.Host.SystemWeb.IntegratedPipeline.IntegratedPipelineContextStage.<RunApp>d__5.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.Runtime.CompilerServices.TaskAwaiter.GetResult() at Microsoft.Owin.Host.SystemWeb.IntegratedPipeline.IntegratedPipelineContext.<DoFinalWork>d__2.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at Microsoft.Owin.Host.SystemWeb.Infrastructure.ErrorState.Rethrow() at Microsoft.Owin.Host.SystemWeb.IntegratedPipeline.StageAsyncResult.End(IAsyncResult ar) at Microsoft.Owin.Host.SystemWeb.IntegratedPipeline.IntegratedPipelineContext.EndFinalWork(IAsyncResult ar) at System.Web.HttpApplication.AsyncEventExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() at System.Web.HttpApplication.ExecuteStep(IExecutionStep step,Boolean& completedSynchronously) | RuntimeMethodInfo.UnsafeInvokeInternal => RuntimeMethodHandle.InvokeMethod => Application.Application_Error 我有点迷茫.我读过两篇文章,但没有一篇给我解决方案.非常感谢任何帮助. 我的最终目标是拥有一个服务于Web Api,MVC和SignalR的内核,并支持OWIN管道. 编辑:由于我得到一个评论,我的案件可能与另一个问题重复,我相信我需要给出一些解释. 我有三个场景. >使用GlobalConfiguration.Configure(WebApiConfig.Register)在Global.asax中进行WebApi初始化,使用NinjectWebCommon和Bootstrapper进行Ninject初始化. 这给了我注入WebApi和SignalR.但由于我想将WebApi初始化移动到OWIN启动,这种方法已经过时了. SignalR注入工作,WebApi注入不起作用. WebApi注入工作,SignalR注入不起作用. 所以基本上我需要弄清楚如何把它放在一起,这样当我在OWIN管道上初始化WebApi时,WebApi和SignalR注入都能正常工作. NinjectWebCommon的代码在下面是原始问题.它包含用于创建SignalR解析器的代码,但在方案3中没有帮助. 编辑2:经过几个小时的试错法后,我得出了一个调用的结论 app.UseNinjectMiddleware(NinjectWebCommon.CreateKernel); app.UseNinjectWebApi(config); 与此电话冲突: GlobalHost.DependencyResolver = new Microsoft.AspNet.SignalR.Ninject.NinjectDependencyResolver(kernel); 所以问题描述对此缩小了.当我使用以下模式时,SignalR停止工作: public void Configuration(IAppBuilder app) { HttpConfiguration config = new HttpConfiguration(); WebApiConfig.Register(config); app.UseNinjectMiddleware(CreateKernel); app.UseNinjectWebApi(config); GlobalHost.HubPipeline.AddModule(new GlobalSignalRExceptionHandler()); app.MapSignalR(); } private static IKernel CreateKernel() { var kernel = new StandardKernel(); GlobalHost.DependencyResolver = new Microsoft.AspNet.SignalR.Ninject.NinjectDependencyResolver(kernel); DependencyResolver.SetResolver(new Ninject.Web.Mvc.NinjectDependencyResolver(kernel)); return kernel; } 但如果我评论这条线 //GlobalHost.DependencyResolver = new Microsoft.AspNet.SignalR.Ninject.NinjectDependencyResolver(kernel); SignalR再次开始工作.但当然没有在集线器内注入. 解决方法
最后,我设法获得了支持OWIN管道,WebApi,MVC和SignalR的工作Ninject配置.
当我发布问题时,我有一个解决方法(在SignalR集线器中禁用了DI),所以我决定不再浪费时间在这上面并继续前进. 但是,当我尝试使用我的启动类运行OWIN内存测试服务器时,发生DI无法正常工作.调用CreateKernel方法太晚,导致创建了在sengleton范围内使用的对象的多个实例. 在使用不同的初始化变体后,我已经使DI工作为OWIN测试服务器,它还修复了SignalR DependencyResolver. 解决方案: 我停止使用Ninject.Web.Common.OwinHost和Ninject.Web.WebApi.OwinHost包这些调用从我的Configuration方法中删除了: //app.UseNinjectMiddleware(NinjectWebCommon.CreateKernel); //app.UseNinjectWebApi(config); 相反,我做了以下事情: public void Configuration(IAppBuilder app) { ConfigureOAuth(app); HttpConfiguration config = new HttpConfiguration(); WebApiConfig.Register(config); app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll); NinjectWebCommon.Start(); config.DependencyResolver = new NinjectDependencyResolver(NinjectWebCommon.bootstrapper.Kernel); app.UseWebApi(config); app.MapSignalR(); } public static class NinjectWebCommon { private static bool _isStarted; internal static readonly Bootstrapper bootstrapper = new Bootstrapper(); /// <summary> /// Starts the application /// </summary> public static void Start() { // When creating OWIN TestService instances during unit tests // Start() method might be called several times // This check ensures that Ninject kernel is initialized only once per process if (_isStarted) return; _isStarted = true; bootstrapper.Initialize(CreateKernel); } /// <summary> /// Creates the kernel that will manage your application. /// </summary> /// <returns>The created kernel.</returns> internal static IKernel CreateKernel() { var kernel = new StandardKernel(); RegisterServices(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) { // DI for SignalR GlobalHost.DependencyResolver = new Microsoft.AspNet.SignalR.Ninject.NinjectDependencyResolver(kernel); // DI for MVC DependencyResolver.SetResolver(new NinjectDependencyResolver(kernel)); // Binding code here kernel.Bind<Something>().ToSelf().InSingletonScope(); } } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- asp.net-mvc – MVC包含路径无效错误
- asp.net – 如何向python中的.aspx页面提交查询
- asp.net-mvc-3 – 为什么我的textBoxFor使用我的路由数据?
- 在ASP.Net Web应用程序中运行后台任务并获得反馈的最佳方法
- asp.net-mvc-4 – 未终止字符串常量MVC4 Razor视图引擎
- asp.net-mvc – 为什么我的ViewModel在[HttpPost]上为空?
- .net – 如何跟踪和消除会话滥用?
- 如果没有授权,如何将用户重定向到ASP.NET页面?
- asp.net-web-api – 密码更改时如何使OAuth令牌无效?
- 如何打印与phpinfo()但ASP.NET类似的信息?
- 这应该是目前最快速有效的ASP.NET Core学习方式(
- GridView用法详解
- asp.net-mvc – 带负载均衡器的SignalR v2
- asp.net – 编辑不适用于Html.DropDownList和@cl
- asp.net-mvc – MVC WebApi不使用AutofacWebApiD
- asp.net-mvc – 为什么ValidateInput(False)不工
- asp.net – 如何在VB.net中处理SqlDataReader nu
- asp.net-mvc – 如何在ASP.NET MVC API控制器中获
- asp.net – 设置值时页面移位 – 我的代码或最新
- asp.net-mvc – 用于OpenID OAuth简单身份验证的