Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Integrating Castle Windsor with SignalR - how should I approach this?

I am getting started with SignalR, and it works great once everything is configured. However, almost all the applications that I work on use Castle Windsor, so it would be great to be able to use them together. The reason that I want to do this is so that I can use Castle dependencies/services inside of a persistent connection.

I dug around in the source code, and it looks like I could either replace DependencyResolver with a Castle based one (i.e., Castle implementing IDependencyResolver), or I could change the usage of DependencyResolver to Castle.

Which one of these is a better idea? Is there another approach that I could use to combine Castle and SignalR?

Thanks, Erick

like image 307
Erick T Avatar asked May 08 '12 23:05

Erick T


1 Answers

August 2016 update

Following from a comment I no longer use the approach below but now use the GlobalHost.DependencyResolver

So in Global.asax.cs I initialise things

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);    
}

and then in the hub

private ILoggingService LoggingService{ get; set; }

    public NotificationHub()
    {
        LoggingService = GlobalHost.DependencyResolver.Resolve<ILoggingService>();
    }

and for completeness

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;
    }

}

OLD ANSWER from 2012

I went with the first option of setting our own DependencyResolver

AspNetHost.SetResolver(new SignalResolver(_container));

I can provide SignalResolver if desired but leaving out for readability for now.

Another important note is that the hubs must have an empty constructor so our castle container injects through properties, e.g.

public class NotificationHub : Hub, INotificationHub
    { 

public INotificationService NotificationService { get; set; }

and the resolver requested

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;
            }
        }
    }
like image 184
dove Avatar answered Oct 08 '22 12:10

dove