So far so good.

The implementation described in the previous article has some “hidden initialization matters”. Let me explain: I use Global.asax to initialize much of my modules. To provide more details:

  1. I initialize Castle.Windsor in Global.asax to leverage the HttpApplication events, i.e. I create the WindosrContainer instance in the Application_Start and in the Dispose phase I can dispose the container as explained in this article
  2. In the same Application_Start phase I can configure all the other components, passing the DI container everywhere it’s necessary, i.e. in the NeventStore installer or in the WebApi CompositionRoot, as described in the same article above
  3. In addition to this I set-up SignalR that is written as an Owin compatible module, so we need to create our Owin middleware/module. To know more detail about that, you can read this good introduction

So, where is the problem?

How if we need the Dependency Injection in SignalR?

As explained in this tutorial, we’ll use this kind of initial Hub configuration, that’s configuring a dependency resolver specific of the container you are using:

public class Startup
{
	public void Configuration(IAppBuilder app)
	{
		app.MapSignalR(new HubConfiguration
		{
			Resolver = new WindsorDependencyResolver(container)
		});
	}
}

With Castle.Windsor, the resolver looks like the following

public class WindsorDependencyResolver : DefaultDependencyResolver
{
	private readonly IWindsorContainer _container;

	public WindsorDependencyResolver(IWindsorContainer container)
	{
		if (container == null)
			throw new ArgumentNullException("container");

		_container = container;
	}

	public override object GetService(Type serviceType)
	{
		return _container.Kernel.HasComponent(serviceType) ? _container.Resolve(serviceType) : base.GetService(serviceType);
	}

	public override IEnumerable<object> GetServices(Type serviceType)
	{
		return _container.Kernel.HasComponent(serviceType) ? _container.ResolveAll(serviceType).Cast<object>() : base.GetServices(serviceType);
	}
}

But where does the container come from in the Hub configuration?

That is the point. As explained above, the DI container needs to be disposed and to do that I’ve created and disposed the container in Global.asax (honestly I haven’t figured out how to dispose the DI container in Owin configurations); so I can see two main options:

  1. Create a public static reference to the container in Global.asax, as explained in this article. I don’t like too much this solution, because it forces to expose your DI container as public throughout all the application, and probably it’s not what you want to do.
  2. Move all the initialization logic from Global.asax.Application_Start to Owin middleware configuration, forgetting about disposing (manually) the container

Are there better ways?

Comments