If you’re finding this post odds are that you’ve found some of the latest greatest (as of now) tools and concepts storming through the .NET world, but you’ve stumbled upon something that just doesn’t seem right. Congratulations, you’re a developer now! But seriously lets get to why you’re here. This post will be an ever-evolving documentation of the issues I’ve stumbled upon and hope it helps you in quest to greatness! Grab another cup of coffee and lets start stirring up our code.
OWIN Integration
So OWIN (Open Web Interface for .NET) is all the craze for ASP.NET web developers and it is for a good right. Not to get into the specifics of why you should use it and the whole mantra behind it, just use it in any new applications. So that is were I was a few days ago, I started a new application for fun and began integrating all the normal NuGet packages I did two years ago (been a while for web development). I quickly learned how much I was left behind; it was time to put some mud boots on and begin digging around. Lets see what was dug up!
Below is the basic of a Startup class for OWIN.
public class Startup { public void Configuration(IAppBuilder app) { } }
Everything we do to setup our site is basically an extension method off IAppBuilder; which allows us to do some pretty neat things. So starting from the top, we’ll want to register SignalR and we’ll end up doing the simplest registration to get it up and running:
public void Configuration(IAppBuilder app) { app.MapSignalR(); }
Pretty easy right!
Autofac & SignalR
Awesome, now lets register Autofac as our dependency resolver using OWIN. Majority comes from Autofac’s documentation on SignalR found here.
public void Configuration(IAppBuilder app) { app.MapSignalR(); var builder = new Builder(); //For us lazy people: builder.RegisterSource(new AnyConcreteTypeNotAlreadyRegisteredSource()); 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); var builder = container.Build(); }
Looks good right? In fact it does, so you run it but your not able to access your SignalR hubs. Getting an error with resolving something like:
“Microsoft.SignalR.IMessageBus messageBus can not be resolved”
WHAT IN THE WORLD!?!? Yea very bizarre issue, but that’s how you found this post!
The issue is actually with our registration calls (go figure). The culprit is (drum roll)…
builder.RegisterSource(new AnyConcreteTypeNotAlreadyRegisteredSource());
That’s right our awesome AnyConcreteTypeNotAlreadyRegisterSource is causing an internal conflict with SignalR’s resolver. Now I’m not sure (yet) why this is happening under the hood, but I’ve managed to figure out a solution. AnyConcreteTypeNotAlreadyRegisterSource has an overloaded parameter that takes in a delegate which can solve this issue:
public void Configuration(IAppBuilder app) { ... builder.RegisterSource(new AnyConcreteTypeNotAlreadyRegisteredSource(TypeRegistation)); ... } private bool TypeRegistation(Type type) { if (type.FullName.StartsWith("Microsoft.AspNet.SignalR")) return false; return true; }
That’s the ‘magic’ to make it work. When ever Autofac tries to resolve a concrete type, it will pass the type through this method and expect a boolean on whether or not it may instantiate that type. Since, we do not wish for it to resolve anything with SignalR, we simply check that FullName starts with “Microsoft.AspNet.SignalR”.
I hope this section helps save some hair in the world!
Till next time!