Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using an existing IoC Container in SignalR 2.0

How can I use an existing IoC with SignalR 2.0?

From the tutorial, it seems I need to setup a class to be called from OWIN via an attribute:

using Microsoft.Owin;
using Owin;
[assembly: OwinStartup(typeof(SignalRChat.Startup))]
namespace SignalRChat
{
    public class Startup
    {
        public void Configuration(IAppBuilder app /*HOW AM I GONNA GET UNITY CONTAINER HERE?*/) 
        {
            var hubConfig = new HubConfiguration()
            {
                EnableJSONP = true,
                EnableDetailedErrors = true,
                EnableJavaScriptProxies = true,
                Resolver = new SignalRUnityDependencyResolver(container)  
            };


            // Any connection or hub wire up and configuration should go here
            app.MapSignalR(hubConfig);
        }
    }
}

The problem here is that I already have a container, that's boot strapped and there are singleton instances in the container that needs to be shared with the MVC app shared under the same host.

However the trouble here is that unlike before, it doesn't look like I can call the MapSignalR method from my own code. Rather I need to rely on OWIN to do this for me. However OWIN is not aware of the container that I already setup.

What's the best way to resolve this? I have some very crude ideas how to hack a solution together using static variables to hold some of these - but I hate the very thought of it. The code will be brittle and order of operation could easily introduce a subtle bug.

Is there a way to get a hold of the IAppBuilder instance without having OWIN invoke the above method? This way I can control better when SignalR gets initialized and I can pass my own IoC into the configuration.

like image 243
Alwyn Avatar asked Nov 04 '13 06:11

Alwyn


1 Answers

In my case I have created a custom hub activator which uses a shared container between my app and signalR (by constructor injection) that way you´ll have single composite root for the whole application.

try the following:

public class CustomHubActivator : IHubActivator
    {
        private readonly Container _container;

        public MseHubActivator(Container container)
        {
            _container = container;
        }

        public IHub Create(HubDescriptor descriptor)
        {
            return _container.GetInstance(descriptor.HubType) as IHub;
        }
    }

register your custom hub activator when you´re bootstrapping your app (maybe the global.asax)

 GlobalHost.DependencyResolver.Register(typeof (IHubActivator),
                                                   () => new CustomHubActivator(Container));

that´s much simplier solution rather than to configure again the signalR dependencyResolver

like image 91
pedrommuller Avatar answered Oct 06 '22 17:10

pedrommuller