4

I'm trying to add a notification system to my MVC web app using SignalR. I want to trigger notifications when certain actions occur in the controllers.

Getting the SignalR 2 up and running was a doddle thanks to Microsoft's excellent SignalR documentation, but I'm struggling to work out how to now change that code to use Autofac for DI, so that I can inject the hub, or something that allows me to access the hub, into controller.

I've set up the Autofac dependency resolver as per the example in the Autofac documentation:

public class Startup
{
    public void Configuration(IAppBuilder app)
    {
        app.UseCookieAuthentication(new CookieAuthenticationOptions
        {
            AuthenticationType = "ApplicationCookie",
            LoginPath = new PathString("/Account/Login"),
            CookieName = "fornet"
        });


        var builder = new ContainerBuilder();

        // STANDARD SIGNALR SETUP:

        // Get your HubConfiguration. In OWIN, you'll create one
        // rather than using GlobalHost.
        var config = new HubConfiguration();

        // Register your SignalR hubs.
        builder.RegisterHubs(Assembly.GetExecutingAssembly());

        // Set the dependency resolver to be Autofac.
        var container = builder.Build();
        config.Resolver = new AutofacDependencyResolver(container);

        // OWIN SIGNALR SETUP:

        // Register the Autofac middleware FIRST, then the standard SignalR middleware.
        app.UseAutofacMiddleware(container);
        app.MapSignalR("/signalr", config);

    }
}

And added a hub:

public class TestHub : Hub
{
    public ITest Test { get; set; }
    public void Hello()
    {
        Test.DoStuff();
    }

    public override Task OnConnected()
    {
        Clients.Caller.hello("Welcome!");
        return base.OnConnected();
    }
}

but now I can't work out how to inject the hubs into my controller. I've tried public SettingsController(IHubContext hubContext), public SettingsController(IHubContext<TestHub> hubContext), public SettingsController(IHubConnectionContext<TestHub> hubConnectionContext) and public SettingsController(TestHub hubConnectionContext), but they all give me exceptions.

What's the right way to inject a hub?

Edit: I should say I've read a lot of SO questions relating to this but haven't found the answer. Those questions either specifically related to different versions of Autofac and SignalR or the dates suggest they would.

Edit 2: I'm using the Autofac.SignalR 3.0.2 NuGet package, but there is also the Autofac.SignalR2 4.0.0, I'm not sure if I should be using that instead?

tomRedox
  • 28,092
  • 24
  • 117
  • 154

1 Answers1

0

Not sure if this is exactly what you need, but I believe you can access your hub in a controller using the following:

var hub = GlobalHost.ConnectionManager.GetHubContext<yoursignalrnamespace.yourhubname>();

Then post notifications or the likes:

hub.Clients.All.postnotification("notified!")
Rob
  • 199
  • 21
  • Thanks Rob, I think you're not supposed to use GlobalHost if you're using OWIN(or possibly DI)? The Autofac docs mention that here http://autofaccn.readthedocs.io/en/v4.0.0/integration/signalr.html. Ideally I just want to pass an interface to the hub, or something that can get the hub, into my controller so I can isolate everything for testing. – tomRedox Oct 25 '17 at 12:55
  • 1
    Ah, fair enough, I gathered it might not exactly be what you wanted but thought I'd mention it anyhow just in case. Good luck finding a solution. – Rob Oct 26 '17 at 09:56