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連接,因此應該可以很好地工作。我會繼續關注垃圾收集,只是爲了確保一切都得到正確清理。這種依賴本身可能會被重構,但是我的某些集線器會有類似的依賴關係。 –

相關問題