我开始使用SignalR,一旦完成所有配置,它都能很好地工作.但是,我工作的几乎所有应用程序都使用Castle Windsor,因此能够将它们组合在一起会很棒.我想这样做的原因是我可以在持久连接中使用Castle依赖项/服务.
我在源代码中挖了一下,看起来我可以用基于Castle的一个替换DependencyResolver(即,实现IDependencyResolver的Castle),或者我可以将DependencyResolver的用法更改为Castle.
哪一个是更好的主意?我可以使用另一种方法来组合Castle和SignalR吗?
谢谢,
埃里克
解决方法
2016年8月更新
在评论之后,我不再使用下面的方法,但现在使用GlobalHost.DependencyResolver
所以在Global.asax.cs中我初始化了一些东西
public static void Init(IWindsorContainer container) { var conn = configurationManager.ConnectionStrings["SRsql"].ConnectionString; GlobalHost.DependencyResolver.Register(typeof(IHubActivator),() => new SignalHubActivator(container)); GlobalHost.DependencyResolver.Register(typeof(ILoggingService),container.Resolve<ILoggingService>); //etc or you could just pass your existing container to the resolver GlobalHost.DependencyResolver.UsesqlServer(conn); }
然后在中心
private ILoggingService LoggingService{ get; set; } public NotificationHub() { LoggingService = GlobalHost.DependencyResolver.Resolve<ILoggingService>(); }
并且为了完整性
public class SignalHubActivator: IHubActivator { private readonly IWindsorContainer _container; public SignalHubActivator(IWindsorContainer container) { _container = container; } public IHub Create(HubDescriptor descriptor) { var result= _container.Resolve(descriptor.HubType) as IHub; if (result is Hub) { _container.Release(result); } return result; } }
从2012年开始回答老问题
我选择了第一个设置我们自己的DependencyResolver的方法
AspNetHost.SetResolver(new SignalResolver(_container));
如果需要,我可以提供SignalResolver,但暂时不考虑可读性.
另一个重要的注意事项是集线器必须有一个空的构造函数,所以我们的城堡容器通过属性注入,例如
public class NotificationHub : Hub,INotificationHub { public INotificationService NotificationService { get; set; }
和解析器要求
public class SignalResolver : DefaultDependencyResolver { private readonly IWindsorContainer _container; public SignalResolver(IWindsorContainer container) { if (container == null) { throw new ArgumentNullException("container"); } _container = container; } public override object GetService(Type serviceType) { return TryGet(serviceType) ?? base.GetService(serviceType); } public override IEnumerable<object> GetServices(Type serviceType) { return TryGetAll(serviceType).Concat(base.GetServices(serviceType)); } private object TryGet(Type serviceType) { try { return _container.Resolve(serviceType); } catch (Exception) { return null; } } private IEnumerable<object> TryGetAll(Type serviceType) { try { var array = _container.ResolveAll(serviceType); return array.Cast<object>().ToList(); } catch (Exception) { return null; } } }