【问题标题】:Ninject Owin Request Scope Silently FailsNinject Owin 请求范围静默失败
【发布时间】:2015-05-04 20:22:58
【问题描述】:

问题 - Ninject 内核总是返回新实例,即使它们的范围是请求。

-我将 OWIN 与 SystemWeb 主机包一起使用以允许我使用 IIS。

-该项目依赖于一个 API 应用程序,该应用程序安装了所有必要的 Ninject/owin 库。

app.UseNinjectMiddleware(CreateKernel).UseNinjectWebApi(config);

-在转换为 OWIN 之前,一切都按预期工作。

-只创建一个内核实例。

-注册了一些全局过滤器,它们在请求范围的对象上设置某些属性。

        public override void OnActionExecuting(HttpActionContext actionContext)
        {
            var accountService = Startup.Kernel.Get<IAccountService>();
            // some changes to accountService etc.

-当管道中的其他过滤器尝试获取IAccountService 的实例时,它们总是返回一个新实例。

根据我自己的研究工作,这似乎是一个已知问题。任何想法,将不胜感激。谢谢。

【问题讨论】:

  • 如果 HttpContext.Currentnull .InRequestScope() 的行为类似于 .InTransientScope()。我不喜欢这种行为(我认为它应该抛出异常),但它就是这样。不过,我不知道你的情况是什么触发因素 - 所以你可能需要调查为什么没有HttpContext
  • @BatteryBackupUnit 假设HttpContext 为空,我不确定我能做些什么。允许应用程序在 IIS 上运行的 SystemWeb 主机包表示它使用 ASP.NET 管道,该管道应设置为HttpContext。注意,没有项目引用 System.Web.dll。明天我会通过添加它来检查HttpContext 是否为空。

标签: dependency-injection ninject owin


【解决方案1】:

我见过类似的问题,也许这是你的情况。

InRequestScope 在以下情况下不起作用:

单独程序集中带有 OWIN 的 Web API。该程序集具有 Ninject 和 Web API,并且 OWIN 将其安装在其中。

仅引用前一个程序集的空 ASP.Net Web 项目。 ASP.Net Web 项目没有安装 Web API 或 Ninject,它只是具有允许 OWIN 托管在 ASP.Net 之上的包。

在该设置中,Ninject 似乎工作得很好;除了 InRequestScope 被忽略并始终解析对象的不同实例。

问题在于 VS 没有将所有需要的程序集复制到结果目录,因为它们没有被应用程序直接引用,也没有被 OWIN 程序集使用,而是被 Ninject 动态加载。

要解决此问题,只需在您的 ASP.Net Web 项目中使用 NuGet Ninject.Extensions.ContextPreservation

也许这只是你的问题,或者是类似的。查看Ninject Extensions 并尝试确定您需要的未添加到结果目录的扩展。

【讨论】:

  • 我尝试在主项目中添加 ContextPreservation 和所有其他 ninject 包,但无济于事。我绝对相信这个答案是正确的。
  • 了解您的问题是否相似的最佳方法是创建一个没有单独程序集的新项目并尝试 InRequestScope。
【解决方案2】:

只是为了补充答案;您可能会发现,除了(对于“IDisosable”对象)“Dispose()”没有被调用之外,绑定的停用处理程序(如果存在)也没有被调用(但激活处理程序仍然会),例如:

            Bind<IThingSvc>().To<ThingSvc>()
                .InRequestScope()
                .OnActivation((ctx, x) => Debug.WriteLine($"Ninject:Activation - '{x.GetType()}' (- '{ctx.GetScope()?.GetType()}')"))
                .OnDeactivation((ctx, x) => Debug.WriteLine($"Ninject:Deactivation - '{x.GetType()}' (- '{ctx.GetScope()?.GetType()}')"));

看起来“Ninject.Extensions.ContextPreservation”被“NamedScope”扩展引用 - “NamedScopeExtensionMethods.cs: IsCurrentResolveRoot()”。

您可能会发现所有 OWIN-Host 覆盖都无法正常工作/加载 - 例如未加载“OwinWebApiModule”模块(如果您查询内核),甚至可能出现如下错误消息(- 指的是 OWIN 命名范围 - 'Ninject_WebApiScope'/"internal const string WebApiScopeName = "Ninject_WebApiScope";") :

[16:29:10] 例外: E0434F4D.Ninject.Extensions.NamedScope.UnknownScopeException(“错误 激活 ApplicationUserManager 的范围 Ninject_WebApiScope 不是 在当前上下文中已知。没有可用的匹配范围,并且 该类型声明为 InNamedScope(Ninject_WebApiScope)。

【讨论】:

    猜你喜欢
    • 2015-02-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-08-11
    • 2017-01-10
    • 2018-09-30
    相关资源
    最近更新 更多