4

我想将SignalR 2带入一个现有项目,在该项目中使用autofac执行所有依赖项注入,并且在Global.asax中执行所有依赖项配置。我发现Autofac.SignalR包使用SignalR和autofac及其accompanying documentation在MVC 5应用程序中使用autofac注入SignalR Hub的依赖关系

我遵循提供的文档中的示例,并遵循使用RegisterHubs函数的建议,而不是定义我的各个集线器依赖项。

不幸的是我的HUB类试图从lifetimeScope

Autofac.Core.DependencyResolutionException was unhandled by user code 
HResult=-2146233088 
Message=No scope with a Tag matching 'AutofacWebRequest' is 
visible from the scope in which instance was requested. 
This generally indicates that a component registered as per-HTTP 
request is being requested by a SingleInstance() component 
(or a similar scenario.) Under the web integration always request 
dependencies from the DependencyResolver.Current or 
ILifetimeScopeProvider.RequestLifetime, never from the container itself. 

我一直没能得到DependencyResolver.Current或ILifeTimeScopeProvider为我工作解决的依赖时,得到以下运行时错误。

我的依赖性的配置是如下

var builder = new ContainerBuilder(); 
    .RegisterControllers(typeof (MvcApplication).Assembly); 
    .RegisterHubs(Assembly.GetExecutingAssembly()); 
    ... 
var container = builder.Build(); 

// Set dependency resolver for MVC 
DependencyResolver.SetResolver(new AutofacDependencyResolver(container)); 

// Set dependency resolver for Web API 
GlobalConfiguration.Configuration.DependencyResolver = new AutofacWebApiDependencyResolver(container); 

// Set the dependency resolver for SignalR 
DependencyResolver.SetResolver(new AutofacDependencyResolver(container)); 

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

我还设置了根据该示例我的毂类:

public class BaseHub : Hub 
{ 
    protected readonly ILifetimeScope _hubLifetimeScope; 
    private static IUserSignalRConnectionRepository _userSignalRConnectionRepository; 

    public BaseHub(ILifetimeScope lifetimeScope) : base() 
    { 
     _hubLifetimeScope = lifetimeScope.BeginLifetimeScope(); 

     _userSignalRConnectionRepository = _hubLifetimeScope.Resolve<IUserSignalRConnectionRepository>(); 
    } 

    protected override void Dispose(bool disposing) 
    { 
     // Dipose the hub lifetime scope when the hub is disposed. 
     if (disposing && _hubLifetimeScope != null) 
      _hubLifetimeScope.Dispose(); 

     base.Dispose(disposing); 
    } 
} 

在幼兽类发生在线路的异常

_userSignalRConnectionRepository = _hubLifetimeScope.Resolve<IUserSignalRConnectionRepository>(); 

回答

4

您应该在注册您的IUserSignalRConnectionRepository的位置包含代码。

错误消息似乎表明此相关性使用InstancePerHttpRequest()进行了注册,这相当于InstancePerMatchingLifetimeScope("AutofacWebRequest")。这个范围是为MVC请求自动创建的,但不适用于SignalR请求(这可能是一件好事,因为它们可以无限期地持续)。

您可以通过致电lifetimeScope.BeginLifetimeScope("AutofacWebRequest");解决此问题。而不是在您的Hub构造函数中使用lifetimeScope.BeginLifetimeScope();

或者,您可以使用InstancePerDependency()(这是默认值)或SingleInstance()而不是InstancePerHttpRequest()来注册IUserSignalRConnectionRepository。

+0

谢谢。您正确地将IUserSignalRConnectionRepository与其他存储库批量注册为InstancePerHttpRequest()。 您使用lifetimeScope.BeginLifetimeScope(“AutofacWebRequest”)的解决方法;似乎工作。 将我的存储库接口注册为InstancePerDependency()或SingleInstance()而不是使用解决方法会有优势吗? 我有一些依赖,我想从集线器以及MVC类引用,所以如果我可以做一个适用于两者的注册将是理想的。 –

+1

我认为使用InstancePerHttpRequest()然后使用lifetimeScope.BeginLifetimeScope(“AutofacWebRequest”)很好。我认为这与使用InstancePerDependency()不同,因为它仅在每个作用域上解析一次。我应该补充一点,SignalR为每个调用实例化一个新的集线器,这个集线器与Web请求不一一对应。在WebSocket的情况下,一个请求负责许多调用。我不认为这真的很重要,除非你的IUserSignalRConnectionRepository取决于每个实际请求创建一次。 – halter73

+0

没有,尽可能少地实例化IUserSignalRConnectionRepository是理想的。它是我需要构建的定制SignalR底板的一部分,用于使用我们的MongoDB数据存储库跟踪负载均衡服务器群中的用户SignalR连接,因此应该可以很好地工作。我会继续关注垃圾收集,只是为了确保一切都得到正确清理。这种依赖本身可能会被重构,但是我的某些集线器会有类似的依赖关系。 –

相关问题