SignalR with Autofac Bootstrapper

We will build off of this example by adding bootstrapping. In this tutorial we will be using Autofac for our IoC, however you can easily follow the majority of the setup, and tweak the bootstrapper dll to use your IoC library of choice.

Tutorial

Step 1 – One change required

The first step is quite easy, follow the introductory tutorial for Signalr. This is very quick, and at the end you will be left with a good starting point to build our horizontally scalable SignalRChat project from.

The tutorial needed one change with the version of jquery:
from this

<script src="~/Scripts/jquery.signalR-2.1.0.min.js"></script>

to this

<script src="~/Scripts/jquery.signalR-2.2.0.min.js"></script>

Step 2 – Update nuget packages

Lets update a few nuget packages in our MVC, just so we make sure we are on the latest stable packages.

Update:

  • Microsoft.AspNet.Mvc
  • Microsoft.AspNet.Razor
  • Microsoft.AspNet.WebPages
  • Microsoft.Owin
  • Microsoft.Owin.Host.SystemWeb
  • Microsoft.Owin.Security

The updated packages below have green checkmarks once complete.

signalrchat_autofac_1

Step 3 – Organize a bit

  1. Create a new folder in the mvc project and name it Hubs
  2. Move ChatHub.cs into this newly created subfolder
  3. Copy and paste the below contents into ChatHub.cs replacing whatever is there now:
    using Microsoft.AspNet.SignalR;
    
    namespace SignalRChat.Hubs
    {
        public class ChatHub : Hub
        {
            public ChatHub(TestClass a)
            {
                var b = a;
            }
            public void Send(string name, string message)
            {
                // Call the addNewMessageToPage method to update clients.
                Clients.All.addNewMessageToPage(name, message);
            }
        }
    
        public class TestClass
        {
            public string Name { get; set; }
        }
    }
    

First, TestClass is only there to allow us to verify that dependency injection is indeed wired up and working.

Step 4 – Make a bootstrapper class library

We will make a new project that will deal with bootstrapping. We can handle all of our dependency registration and setup within this project.

  1. In the MVC project, delete Startup.cs, because we will be moving this functionality to our bootstrapper.
  2. Add a new project to the solution. Make it a C# Class Library. Name it SignalRChat.Web.Bootstrapper
  3. In the new project, rename the default Class1.cs to Startup.cs
  4. Now paste these contents into the file:
    using Autofac;
    using Autofac.Integration.SignalR;
    using Microsoft.AspNet.SignalR;
    using Microsoft.AspNet.SignalR.Hubs;
    using Owin;
    
    namespace SignalRChat.Web.Bootstrapper
    {
        public class Startup
        {
            public void Configuration(IAppBuilder app)
            {
                // Call our IoC static helper method to start the typical Autofac SignalR setup
                var container = IocConfig.RegisterDependencies();
    
                // Get your HubConfiguration. In OWIN, we create one rather than using GlobalHost
                var hubConfig = new HubConfiguration();
    
                // Sets the dependency resolver to be autofac.
                hubConfig.Resolver = new AutofacDependencyResolver(container);
    
                // OWIN SIGNALR SETUP:
    
                // Register the Autofac middleware FIRST, then the standard SignalR middleware.
                app.UseAutofacMiddleware(container);
                app.MapSignalR("/signalr", hubConfig);
            }
        }
    }
    

Now this class file has a few errors because our new bootstrapper project doesn’t have references to these libraries. So we will need to fix these compilation errors and wire up our owin startup. First let’s explain some of the lines here.

var container = IocConfig.RegisterDependencies();

This is a static helper method (which we create in step 5 below), which will register our hubs and any other classes which are necessary.

...
var hubConfig = new HubConfiguration();
...

The rest of the configuration lines have to do with setting the dependency resolver to AutoFac (we aren’t using the built in one provided by .Net Framework anymore) for SignalR and OWIN. The details are all explained nicely here. If you are using a different IoC, this is where you would need to adjust your bootstrapping code appropriately.

Step 5 – IoC setup

  1. Create a new class named IocConfig.cs
  2. Now paste these contents into the file:
    using Autofac;
    using Autofac.Integration.SignalR;
    using SignalRChat.Hubs;
    using System.Reflection;
    
    namespace SignalRChat.Web.Bootstrapper
    {
        public class IocConfig
        {
            public static IContainer RegisterDependencies()
            {
                var builder = new ContainerBuilder();
    
                builder.RegisterType<TestClass>();
    
                // Register your SignalR hubs.
                builder.RegisterHubs(Assembly.Load("SignalRChat.Web"));
    
                return builder.Build();
            }
        }
    }
  3. Right click References > Add References,  and we will add solution references for the MVC project

Now we will install the packages in package manager console with our Default Project: SignalRChat.Web.Bootstrapper

  • install-package microsoft.owin.security -version 3.0.1
  • install-package microsoft.owin.host.systemweb -version 3.0.1
  • install-package microsoft.aspnet.signalr.core -version 2.2.0
  • install-package autofac.owin
  • install-package autofac.signalr

Important note #1: You’ll notice after running all of those nuget commands, the project now has an app.config file. You’ll notice it has some entries for runtime binding redirect, which is needed because signalr.core references older versions. But luckily, Web.config already references these binding redirects, and fortunately the .config file for the executing assembly takes precedence over all others. So in this case, the Web.Config is used, and it already has these exact same runtime binding redirects (plus several others). So you can safely delete app.config if you like, or leave it.

Important note #2: You might also notice that we specified the versions of the nuget packages as well. I made sure these versions matched the versions in our MVC packages.config. signalrchat_autofac_4 We did this because we want to make sure that the version we reference in our SignalRChat.Web.Bootstrapper is the same as the version in the MVC project. A good practice to employ is make your versions match in different projects, because when you bootstrap everything at runtime, there’s less chance to get errors because of incompatible versions.

You will notice that we didn’t bother to include versions for the autofac dependencies. This is because we don’t have autofac as a reference in any other projects in the solution, so I’m not concerned with trying to make the versions match.

We are almost there!

Step 6 – Final settings

Because we are bootstrapping, we want to make sure our assemblies all build to the same /bin folder. This will be the <MVC project dir>/bin. So we will go into the Bootstrapper projects, and edit their build properties to have an output path of: ..\SignalRChat\bin\ for Debug and Release configurations

signalrchat_autofac_6

And the one last step, open the MVC project’s Web.config and add the following in the <appSettings> section

<add key="owin:AppStartup" value="SignalRChat.Web.Bootstrapper.Startup, SignalRChat.Web.Bootstrapper" />

Done!

Now you can run the project, go to the ~/home/chat and it will function as it did before, but we are using IoC with Autofac.

The final solution can be found on github here.

Please check back for another tutorial that builds off of this. We will look at using MassTransit to pass our chat messages around to help the chat application become horizontally scalable.

2 thoughts on “SignalR with Autofac Bootstrapper”

  1. Now using exactly your code, what is the best way to update clients from outside the hub?

    “A common error in OWIN integration is use of the GlobalHost. In OWIN you create the configuration from scratch. You should not reference GlobalHost anywhere when using the OWIN integration.” -taken from the official Autofac SignalR Integration.

    Is this the referenced case? Or they refer to when using Owin Self Host?

    I actually manage to make GlobalHost.ConnectionManager.GetHubContext to work, but I am not sure whether it is best practice.

    Thanks for the great tutorial!

  2. I did take note of that warning in the Autfac, and what I think it’s trying to emphasize is you don’t want to Wire up your bootstrapper with:

    GlobalHost.DependencyResolver = new AutofacDependencyResolver(container);

    Now you want to know how to update the clients from outside the hub? Easy, in the other tutorial here, check out Step 7, you can see the consumer is not a hub, but it still can update a client.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.