SignalR
SignalR集成需要 Autofac.SignalR NuGet 包。
SignalR 集成提供SignalR 集線器的依賴集成。由於 SignalR 是內部構件,所以不支持SignalR每請求的生命周期依賴。
這個文檔主要是關於Autofac的,你有興趣可以點擊這里: 微軟關於SignalR和依賴注入.
快速開始
要使用 Autofac 集成 SignalR 你得引用SignalR集成的 NuGet 包,然后注冊集線器,並設置依賴處理器。
protected void Application_Start() { var builder = new ContainerBuilder(); // 注冊SignalR 集線器. builder.RegisterHubs(Assembly.GetExecutingAssembly()); // 將依賴處理器設置成Autofac. var container = builder.Build(); GlobalHost.DependencyResolver = new AutofacDependencyResolver(container); }
下一節關於這些功能的細節,以及如何使用它們。
注冊集線器
程序啟動時同時建立 Autofac 容器,你需要注冊 SignalR 集線器及其依賴。通常是在OWIN startup 類或 Global.asax中的 Application_Start 中進行。
var builder = new ContainerBuilder(); // 掃描程序集一次性加載... builder.RegisterHubs(Assembly.GetExecutingAssembly()); // ...手動單個注冊. builder.RegisterType<ChatHub>().ExternallyOwned();
如果你注冊單個的集線器,確保是作為 ExternallyOwned()來注冊的。這是為讓SignalR來控制集線的銷毀而不是Autofac。
設置依賴處理器
將建好的容器傳給 AutofacDependencyResolver 類的實例。將新處理器賦給 GlobalHost.DependencyResolver (OWIN的話是HubConfiguration.Resolver ) 讓SignalR 使用AutofacDependencyResolver來定位服務。下邊是IDependencyResolver 接口Autofac的實現。
var container = builder.Build(); GlobalHost.DependencyResolver = new AutofacDependencyResolver(container);
管理依賴生命周期
考慮到不支持每請求的依賴, 所有要處理的SignalR的依賴均來於根容器。
- 如果你有
IDisposable的組件,它們在應用程序的生命周期里一直存活原於Autofac 會 承載它們直到邊界或容器銷毀。 你必須將這些注冊為ExternallyOwned()。 任何組件注冊為InstancePerLifetimeScope()都是單例的。假設只有一個生命周期范圍,你只能獲取一個實例。
為了使您的集線器依賴生命周期更容易管理,您可以將根生命周期范圍注入到集線器的構造函數中。下一步,創建一個子生命期范圍,您可以在您的集線器調用的持續時間內使用,並解決所需的服務。最后,確保SignalR銷毀集線器的時候銷毀子生命期。(這類似於服務定位,但這是獲得“每個集線器”范圍的唯一方法。不,這不是很棒。)
public class MyHub : Hub { private readonly ILifetimeScope _hubLifetimeScope; private readonly ILogger _logger; public MyHub(ILifetimeScope lifetimeScope) { // Create a lifetime scope for the hub. _hubLifetimeScope = lifetimeScope.BeginLifetimeScope(); // Resolve dependencies from the hub lifetime scope. _logger = _hubLifetimeScope.Resolve<ILogger>(); } public void Send(string message) { // You can use your dependency field here! _logger.Write("Received message: " + message); Clients.All.addMessage(message); } 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); } }
如果這是你程序里的常規模式,你可以考慮創建基/抽象集線器,讓其它集線器繼承以節省范圍內的復制/粘貼,創建/銷毀的步驟。
向集線器中注入生命周期范圍並不會產生每請求的范圍。 僅僅給你一個管理依賴生命周期的方法,比在根容器中處理一切來得更有效的方法。使用InstancePerRequest,甚至在工作區,也是會失敗的。更多信息見: the FAQ on per-request scope 。
OWIN 集成
如果 SignalR 作為OWIN應用的一部分來用,你需要:
- 完成所有標准SignalR 集成的資料。 - 注冊控制器,設置依賴處理器等。
- 在 base基礎 Autofac OWIN 集成上設置你的程序
public class Startup { public void Configuration(IAppBuilder app) { var builder = new ContainerBuilder(); // STANDARD SIGNALR SETUP: // Get your HubConfiguration. In OWIN, you'll create one // rather than using GlobalHost. var config = new HubConfiguration(); // Register your SignalR hubs. builder.RegisterHubs(Assembly.GetExecutingAssembly()); // Set the dependency resolver to be Autofac. var container = builder.Build(); config.Resolver = new AutofacDependencyResolver(container); // OWIN SIGNALR SETUP: // Register the Autofac middleware FIRST, then the standard SignalR middleware. app.UseAutofacMiddleware(container); app.MapSignalR("/signalr", config); // To add custom HubPipeline modules, you have to get the HubPipeline // from the dependency resolver, for example: var hubPipeline = config.Resolver.Resolve<IHubPipeline>(); hubPipeline.AddModule(new MyPipelineModule()); } }
OWIN 集成常見錯誤為使用GlobalHost。OWIN中配置你會抓狂. OWIN集成中,任何地方你都不能引用 。 點擊這里查看微軟關於這個和其它Ioc容器的文檔。
