Asp.net-Mvc-3
SignalR + 依賴注入問題
我在我的 MVC3 應用程序中使用 SignalR,並且由於我已經在我的控制器上實現了 StructureMap 依賴注入,我想在我的集線器中做同樣的事情,但我似乎無法讓它工作。
請告訴我下面的程式碼有什麼問題:
SignalRSmDependencyResolver.cs
public class SignalRSmDependencyResolver : DefaultDependencyResolver { private IContainer _container; public SignalRSmDependencyResolver(IContainer container) { _container = container; } public override object GetService(Type serviceType) { object service = null; if (!serviceType.IsAbstract && !serviceType.IsInterface && serviceType.IsClass) { // Concrete type resolution service = _container.GetInstance(serviceType); } else { // Other type resolution with base fallback service = _container.TryGetInstance(serviceType) ?? base.GetService(serviceType); } return service; } public override IEnumerable<object> GetServices(Type serviceType) { var objects = _container.GetAllInstances(serviceType).Cast<object>(); objects.Concat(base.GetServices(serviceType)); return objects; } }SignalRExtensionsRegistry.cs
public class SignalRExtensionsRegistry : Registry { public SignalRExtensionsRegistry() { For<IDependencyResolver>().Add<SignalRSmDependencyResolver>(); } }國際奧委會
public static class IoC { public static IContainer Initialize() { var container = BootStrapper.Initialize(); container.Configure(x => { x.For<IControllerActivator>().Singleton().Use<StructureMapControllerActivator>(); }); return container; } } public class StructureMapControllerActivator : IControllerActivator { public StructureMapControllerActivator(IContainer container) { _container = container; } private IContainer _container; public IController Create(RequestContext requestContext, Type controllerType) { IController controller = DependencyResolver.Current.GetService(controllerType) as IController; return controller; } }AppStart_Structuremap.cs
[assembly: WebActivator.PreApplicationStartMethod(typeof(StoreUI.AppStart_Structuremap), "Start")] namespace MyNameSpace { public static class AppStart_Structuremap { public static void Start() { var container = (IContainer) IoC.Initialize(); DependencyResolver.SetResolver(new StructureMapDependenceyResolver(container)); AspNetHost.SetResolver(new StructureMapDependencyResolver(container)); } } }NotificationsHub.cs
[HubName("notificationsHub")] public class NotificationsHub : Hub { #region Declarations private readonly IUserService userService; #endregion #region Constructor public NotificationsHub(IUserService userService) { this.userService = userService; } #endregion public void updateServer(string message) { Clients.updateClient(message); } }謝謝
將 Structuremap 導入 SignalR 實際上非常容易。首先,您要創建自己的解析器:
StructureMap 解析器
用途:
using SignalR.Infrastructure; using StructureMap;班級:
public class StructureMapResolver : DefaultDependencyResolver { private IContainer _container; public StructureMapResolver(IContainer container) { _container = container; } public override object GetService(Type serviceType) { object service = null; if (!serviceType.IsAbstract && !serviceType.IsInterface && serviceType.IsClass) { // Concrete type resolution service = _container.GetInstance(serviceType); } else { // Other type resolution with base fallback service = _container.TryGetInstance(serviceType) ?? base.GetService(serviceType); } return service; } public override IEnumerable<object> GetServices(Type serviceType) { var objects = _container.GetAllInstances(serviceType).Cast<object>(); return objects.Concat(base.GetServices(serviceType)); } }這裡的想法是嘗試使用您的容器來解析依賴項,如果您沒有連接依賴項,請將其傳遞給預設解析器。這樣您就不必擔心 SignalR 中的所有其他依賴項,並且可以只關注您想要注入的內容(Hubs、ConnectionIdFactory、MessageBus 等)。
解析器和集線器的綁定
接下來,您將要在您的容器中註冊它(我喜歡使用系統資料庫):
用途:
using SignalR.Infrastructure; using StructureMap.Configuration.DSL;班級:
public class ExtensionsRegistry : Registry { public ExtensionsRegistry() { For<IDependencyResolver>().Add<StructureMapResolver>(); } }解決更換
最後,您將要告訴 SignalR 使用您的解析器而不是預設值:
Global::Application_Start 或 WebActivator::Pre_Start
用途:
using SignalR.Hosting.AspNet; using SignalR.Infrastructure;應用程序_開始:
// Make sure you build up the container first AspNetHost.SetResolver(StructureMap.ObjectFactory.GetInstance<IDependencyResolver>());具有註入依賴項的愚蠢集線器
現在您可以將您的容器知道的任何依賴項注入集線器本身:
[HubName("defaultHub")] public class DefaultHub : Hub, IDisconnect { private readonly IRepository _repo; public DefaultHub(IRepository repo) { _repo = repo; } public void Connect() { Caller.setUser(Context.ConnectionId); Clients.addMessage(string.Format("{0} has connected", Context.ConnectionId)); } public void MessageSender(string message) { Caller.addMessage(_repo.RepositoryMessage()); Clients.addMessage(message); } public Task Disconnect() { var clientId = this.Context.ConnectionId; return Task.Factory.StartNew(() => { Clients.addMessage(string.Format("{0} has disconnected", clientId)); }); } }