将 Autofac 与 SignalR 结合使用时出现范围错误

2024-03-13

我正在尝试注入HttpContextBase在我的 SignalR 中心:

public class EventHub : Hub, IDisconnect
{
    private readonly HttpContextBase _httpContextBase;

    public EventHub(HttpContextBase httpContextBase)
    {
        _httpContextBase = httpContextBase;
    }

    [...]
}

注册码如下所示:

private static void InitAutofac()
{
    var builder = new ContainerBuilder();

    var assembly = typeof (MvcApplication).Assembly;

    builder.RegisterControllers(assembly).PropertiesAutowired();
    builder.RegisterModule(new AutofacWebTypesModule());
    builder.RegisterFilterProvider();

    builder.RegisterAssemblyTypes(assembly)
        .Where(InterfaceBasedInjectedClasses())
        .AsImplementedInterfaces()
        .InstancePerLifetimeScope();

    builder.RegisterAssemblyTypes(assembly)
        .Where(InterfaceLessInjectedClasses())
        .InstancePerLifetimeScope();

    builder.RegisterType<SurvivalContainer>().InstancePerLifetimeScope();

    builder.RegisterType<EventHub>().InstancePerLifetimeScope();

    var container = builder.Build();

    DependencyResolver.SetResolver(new AutofacDependencyResolver(container));


    GlobalHost.DependencyResolver = new SignalR.Autofac.AutofacDependencyResolver(container);

    RouteTable.Routes.MapHubs();
}

我得到的错误是:

[DependencyResolutionException:没有与标签匹配的范围 “httpRequest”从实例所在的范围可见 要求。这通常表明组件注册为 每个 HTTP 请求正在由 SingleInstance() 组件请求(或 类似的场景。)在网络集成下总是请求 来自 DependencyResolver.Current 的依赖项或 ILifetimeScopeProvider.RequestLifetime,从不来自容器 本身。]

堆栈跟踪:

Autofac.Core.Lifetime.MatchingScopeLifetime.FindScope(ISharingLifetimeScope mostNestedVisibleScope) +160
Autofac.Core.Resolving.InstanceLookup..ctor(IComponentRegistration registration, IResolveOperation context, ISharingLifetimeScope mostNestedVisibleScope, IEnumerable`1 parameters) +57
Autofac.Core.Resolving.ResolveOperation.GetOrCreateInstance(ISharingLifetimeScope currentOperationScope, IComponentRegistration registration, IEnumerable`1 parameters) +102
Autofac.Core.Resolving.ResolveOperation.Execute(IComponentRegistration registration, IEnumerable`1 parameters) +64
Autofac.Core.Lifetime.LifetimeScope.ResolveComponent(IComponentRegistration registration, IEnumerable`1 parameters) +164
Autofac.Core.Container.ResolveComponent(IComponentRegistration registration, IEnumerable`1 parameters) +14
Autofac.ResolutionExtensions.TryResolveService(IComponentContext context, Service service, IEnumerable`1 parameters, Object& instance) +70
Autofac.ResolutionExtensions.TryResolve(IComponentContext context, Type serviceType, Object& instance) +70
SignalR.Autofac.AutofacDependencyResolver.GetService(Type serviceType) in D:\etc\Dev\SignalR.Autofac\AutofacDependencyResolver.cs:30
SignalR.Hubs.DefaultHubActivator.Create(HubDescriptor descriptor) +60
SignalR.Hubs.DefaultHubManager.ResolveHub(String hubName) +27
SignalR.Hubs.HubDispatcher.CreateHub(IRequest request, HubDescriptor descriptor, String connectionId, TrackingDictionary state, Boolean throwIfFailedToCreate) +445
SignalR.Hubs.HubDispatcher.OnReceivedAsync(IRequest request, String connectionId, String data) +246
SignalR.<>c__DisplayClass6.<ProcessRequestAsync>b__4(String data) +29
SignalR.Transports.ForeverTransport.ProcessSendRequest() +63
SignalR.Transports.ForeverTransport.ProcessRequestCore(ITransportConnection connection) +70
SignalR.Transports.ForeverTransport.ProcessRequest(ITransportConnection connection) +5
SignalR.PersistentConnection.ProcessRequestAsync(HostContext context) +560
SignalR.Hubs.HubDispatcher.ProcessRequestAsync(HostContext context) +120
SignalR.Hosting.AspNet.AspNetHandler.ProcessRequestAsync(HttpContextBase context) +422       SignalR.Hosting.AspNet.HttpTaskAsyncHandler.System.Web.IHttpAsyncHandler.BeginProcessRequest(HttpContext context, AsyncCallback cb, Object extraData) +68
System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +301
System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +155

我刚刚开始使用 autofac 和 SignalR,我发现自己有点卡住了。 SO 上的相关主题都没有帮助。知道我做错了什么吗?


问题是这一行:

builder.RegisterModule(new AutofacWebTypesModule());

异常消息表明,在解析过程中,正在尝试从标记为生命周期的范围内解析某些内容httpRequest。当你注册一些东西时,你会在 Autofac 中得到这样的注册InstancePerHttpRequest():

// These two are roughly equivalent:
builder.RegisterType<SomeType>().InstancePerHttpRequest();
builder.RegisterType<SomeType>().InstancePerMatchingLifetimeScope("AutofacWebRequest");

如果你看一下源码AutofacWebTypesModule它注册网络抽象(例如HttpContextBase,你正在寻找的东西)作为InstancePerHttpRequest.

此外,如果你看看Autofac.Integration.Mvc.AutofacDependencyResolver有效,每当您在请求期间解析类型时,它都会创建一个新的、嵌套的、命名的生命周期范围,标记为httpRequest。这让你拥有那种魔力InstancePerHttpRequest.

假设下SignalR.Autofac你正在使用的库是这里的那个 https://github.com/thinktecture/SignalR.Autofac,这也是NuGet 上的那个 http://nuget.org/packages/SignalR.AutoFac), 寻找SignalR.Autofac.AutofacDependencyResolver https://github.com/thinktecture/SignalR.Autofac/blob/master/AutofacDependencyResolver.cs, 没有为服务解析创建此类嵌套/命名生命周期范围.

因此,当 Autofac 尝试解决HttpContextBase依赖,它找不到httpRequest标记范围(因为它不存在)并发出您看到的错误。

这个问题没有简单的答案。嵌套的httpRequest范围实际上很重要,因为它基本上不可能存在outside真实的网络请求。它使它变得“安全”——你无法得到HttpContextBase如果没有网络上下文(例如,在应用程序启动时)。

如果您需要注入HttpContextBase并且您确定您的EventHub仅适用于一个网络请求,仅此而已(我不是 SignalR 人员,所以请耐心等待),这意味着您需要:

  • 请求 SignalR.Autofac 项目修复此问题。
  • 实现您自己的自定义 SignalR.Autofac.AutofacDependencyResolver,它以 MVC 解析器的方式处理事务。

如果没有亲自实际完成这项工作并对其进行测试,我无法真正提供有关如何实现这一目标的具体指导。这个练习留给读者。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

将 Autofac 与 SignalR 结合使用时出现范围错误 的相关文章

  • 如何将 std::string& 转换为 C# 引用字符串

    我正在尝试将 C 函数转换为std string参考C 我的 API 如下所示 void GetStringDemo std string str 理想情况下 我希望在 C 中看到类似的东西 void GetStringDemoWrap r
  • BASIC 中的 C 语言中的 PeekInt、PokeInt、Peek、Poke 等效项

    我想知道该命令的等效项是什么Peek and Poke 基本和其他变体 用 C 语言 类似PeekInt PokeInt 整数 涉及内存条的东西 我知道在 C 语言中有很多方法可以做到这一点 我正在尝试将基本程序移植到 C 语言 这只是使用
  • 在一个数据访问层中处理多个连接字符串

    我有一个有趣的困境 我目前有一个数据访问层 它必须与多个域一起使用 并且每个域都有多个数据库存储库 具体取决于所调用的存储过程 目前 我只需使用 SWITCH 语句来确定应用程序正在运行的计算机 并从 Web config 返回适当的连接字
  • 通过引用传递 [C++]、[Qt]

    我写了这样的东西 class Storage public Storage QString key const int value const void add item QString int private QMap
  • 如何从本机 C(++) DLL 调用 .NET (C#) 代码?

    我有一个 C app exe 和一个 C my dll my dll NET 项目链接到本机 C DLL mynat dll 外部 C DLL 接口 并且从 C 调用 C DLL 可以正常工作 通过使用 DllImport mynat dl
  • 访问外部窗口句柄

    我当前正在处理的程序有问题 这是由于 vista Windows 7 中增强的安全性引起的 特别是 UIPI 它阻止完整性级别较低的窗口与较高完整性级别的窗口 对话 就我而言 我想告诉具有高完整性级别的窗口进入我们的应用程序 它在 XP 或
  • 方程“a + bx = c + dy”的积分解

    在等式中a bx c dy 所有变量都是整数 a b c and d是已知的 我如何找到整体解决方案x and y 如果我的想法是正确的 将会有无限多个解 由最小公倍数分隔b and d 但我只需要一个解决方案 我可以计算其余的 这是一个例
  • 使用 C# 中的 CsvHelper 将不同文化的 csv 解析为十进制

    C 中 CsvHelper 解析小数的问题 我创建了一个从 byte 而不是文件获取 csv 文件的类 并且它工作正常 public static List
  • 为什么这个字符串用AesCryptoServiceProvider第二次解密时不相等?

    我在 C VS2012 NET 4 5 中的文本加密和解密方面遇到问题 具体来说 当我加密并随后解密字符串时 输出与输入不同 然而 奇怪的是 如果我复制加密的输出并将其硬编码为字符串文字 解密就会起作用 以下代码示例说明了该问题 我究竟做错
  • 两个类可以使用 C++ 互相查看吗?

    所以我有一个 A 类 我想在其中调用一些 B 类函数 所以我包括 b h 但是 在 B 类中 我想调用 A 类函数 如果我包含 a h 它最终会陷入无限循环 对吗 我能做什么呢 仅将成员函数声明放在头文件 h 中 并将成员函数定义放在实现文
  • C 编程:带有数组的函数

    我正在尝试编写一个函数 该函数查找行为 4 列为 4 的二维数组中的最大值 其中二维数组填充有用户输入 我知道我的主要错误是函数中的数组 但我不确定它是什么 如果有人能够找到我出错的地方而不是编写新代码 我将不胜感激 除非我刚去南方 我的尝
  • LINQ:使用 INNER JOIN、Group 和 SUM

    我正在尝试使用 LINQ 执行以下 SQL 最接近的是执行交叉联接和总和计算 我知道必须有更好的方法来编写它 所以我向堆栈团队寻求帮助 SELECT T1 Column1 T1 Column2 SUM T3 Column1 AS Amoun
  • C# 动态/expando 对象的深度/嵌套/递归合并

    我需要在 C 中 合并 2 个动态对象 我在 stackexchange 上找到的所有内容仅涵盖非递归合并 但我正在寻找能够进行递归或深度合并的东西 非常类似于jQuery 的 extend obj1 obj2 http api jquer
  • 复制目录下所有文件

    如何将一个目录中的所有内容复制到另一个目录而不循环遍历每个文件 你不能 两者都不Directory http msdn microsoft com en us library system io directory aspx nor Dir
  • C# 中的 IPC 机制 - 用法和最佳实践

    不久前我在 Win32 代码中使用了 IPC 临界区 事件和信号量 NET环境下场景如何 是否有任何教程解释所有可用选项以及何时使用以及为什么 微软最近在IPC方面的东西是Windows 通信基础 http en wikipedia org
  • 使用特定参数从 SQL 数据库填充组合框

    我在使用参数从 sql server 获取特定值时遇到问题 任何人都可以解释一下为什么它在 winfom 上工作但在 wpf 上不起作用以及我如何修复它 我的代码 private void UpdateItems COMBOBOX1 Ite
  • 当文件流没有新数据时如何防止fgets阻塞

    我有一个popen 执行的函数tail f sometextfile 只要文件流中有数据显然我就可以通过fgets 现在 如果没有新数据来自尾部 fgets 挂起 我试过ferror and feof 无济于事 我怎样才能确定fgets 当
  • 指针和内存范围

    我已经用 C 语言编程有一段时间了 但对 C 语言还是很陌生 有时我对 C 处理内存的方式感到困惑 考虑以下有效的 C 代码片段 const char string void where is this pointer variable l
  • Mono 应用程序在非阻塞套接字发送时冻结

    我在 debian 9 上的 mono 下运行一个服务器应用程序 大约有 1000 2000 个客户端连接 并且应用程序经常冻结 CPU 使用率达到 100 我执行 kill QUIT pid 来获取线程堆栈转储 但它总是卡在这个位置
  • 从 mvc 控制器使用 Web api 控制器操作

    我有两个控制器 一个mvc控制器和一个api控制器 它们都在同一个项目中 HomeController Controller DataController ApiController 如果我想从 HomeController 中使用 Dat

随机推荐