我在我的MVC3应用程序中使用SignalR,并且由于我已经在我的控制器上实现了StructureMap依赖注入,所以我想在我的中心做同样的事情,但是我似乎无法使其工作。
SignalRSmDependencyResolver.cs@H_502_3@
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@H_502_3@
public class SignalRExtensionsRegistry : Registry { public SignalRExtensionsRegistry() { For<IDependencyResolver>().Add<SignalRSmDependencyResolver>(); } }
IoC.cs@H_502_3@
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@H_502_3@
[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)); } } }
[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); } }
谢谢@H_502_3@
解决方法
将Structuremap转换成SignalR其实很简单。首先要创建自己的解析器:
StructureMap Resolver@H_502_3@
用途:@H_502_3@
using SignalR.Infrastructure; using StructureMap;
类:@H_502_3@
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等)上。@H_502_3@
接下来,您将要在容器中注册(我喜欢使用注册表):@H_502_3@
用途:@H_502_3@
using SignalR.Infrastructure; using StructureMap.Configuration.DSL;
类:@H_502_3@
public class ExtensionsRegistry : Registry { public ExtensionsRegistry() { For<IDependencyResolver>().Add<StructureMapResolver>(); } }
拆卸变更@H_502_3@
最后,您将要告诉SignalR使用您的解析器而不是默认值:@H_502_3@
Global :: Application_Start或WebActivator :: Pre_Start@H_502_3@
用途:@H_502_3@
using SignalR.Hosting.AspNet; using SignalR.Infrastructure;
Application_Start:@H_502_3@
// Make sure you build up the container first AspNetHost.SetResolver(StructureMap.ObjectFactory.GetInstance<IDependencyResolver>());
Silly Hub与注入的依赖关系@H_502_3@
现在,您可以将容器知道的任何依赖项注入到集线器本身中:@H_502_3@
[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)); }); } }