Dependency Inject with SignalR & Castle Windsor

Setting up SignalR with Castle Windsor is relatively straight forward. This is after I messed around trying to get it work for a while. The example setup in this blog is using SignalR 2, Owin and Castle Windsor.

The example contains a hub which provides random numbers to clients, not very exciting but should hopefully be useful enough for this example. The hub code is as follows.

  [HubName("randomNumberHub")]  
   public class RandomNumberHub : Hub  
   {  
     private readonly ILogger _log;  
     public IRandomNumberGenerator Generator { get; set; }  
     public RandomNumberHub(ILogger logger)   
     {  
       _writer = writer;  
     }  
     public void GetRandomNumber()  
     {  
       _logger.Log("Get Random Number Called");
       Clients.All.updateRandomNumber(Generator.Random());  
     }  
   }  

In the example above we have provided IRandomNumberGenerator public property as we want to make sure that property inject is working and also ILogger which is provided through the constructor.

Now we need to provide a custom Dependency Resolver which we will provide when configuring SignalR in the “startup.cs”.

   public class SignalRDependencyResolver : DefaultDependencyResolver  
   {  
     private readonly IWindsorContainer _container;  
     public SignalRDependencyResolver(IWindsorContainer container)  
     {  
       if (container == null)  
       {  
         throw new ArgumentNullException(nameof(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);  
     }  
   }  

The above class is from the signalR.Castle.Windsor nuget package which can be found here Nuget Package. Although if you don’t want to install the package just use the code above.

We now have to provide a HubConfiguration for when we map SignalR in the startup class.

  private static HubConfiguration CreateHubConfiguration()  
     {  
       var signalrDependency = new SignalRDependencyResolver(_container);  
       var configuration = new HubConfiguration { Resolver = signalrDependency };  
       return configuration;  
     }  

Here we are setting the Hub Configurations resolver to our SignalRDependencyResolver.

The last step is to now provide our HubConfiguration when we Map SignalR which is nice and simple.

 app.MapSignalR(CreateHubConfiguration());  

That’s it, all done.

Using Castle Windsor with Azure Web Job

Azure Web Jobs are pretty cool to use, you can be up and running receiving messages from a Service Bus within minutes. But after messing around you probably want to wire up something useful, for myself Castle Windsor was a must. This was the solution that I used.

 class Program  
   {  
     static void Main()  
     {  
       var container = new WindsorContainerFactory().Create();  
       var config = new JobHostConfiguration  
       {  
         JobActivator = new ExampleActivator(container)  
       };  
       config.UseServiceBus();  
       var host = new JobHost(config);  
       host.RunAndBlock();  
     }  
   }  

We are creating a new WebJobConfiguration and providing our own JobActivator (Defines an activator that creates an instance of a job type).

FYI In the example above WindsorContainerFactory().Create() is just newing up a Windsor container and registering my installers.

The IJobActivator implementation looks something like this:

 public class ExampleActivator : IJobActivator  
   {  
     private readonly IWindsorContainer _container;  
     public ExampleActivator(IWindsorContainer container)  
     {  
       _container = container;  
     }  
     public T CreateInstance<T>()  
     {  
       return _container.Resolve<T>();  
     }  
   }  
 }  

Job done, your Castle Windsor container is wired up.

Using NSubstitute to Test MVC Request

After performing a code review I noticed developers were creating virtual methods in controllers so that they code unit test methods that contained Request.RawUrl. This is a cut down example:

  public ActionResult About()  
     {  
       ViewBag.Message = "Your application description page.";  
       if (GetUrl().Contains("About"))  
       {  
         ViewBag.Message = "Contains About in raw url";  
       }  
       return View();  
     }  
     public virtual string GetUrl()  
     {  
       return Request.RawUrl;  
     }  

This would allow for a unit test that looked something like this:

     public class MockHomeController : HomeController  
     {  
       public override string GetUrl()  
       {  
         return @"\About";  
       }  
     }  
     [Fact]  
     public void Test_About_Logic()  
     {  
       var homeController = new MockHomeController();  
       homeController.About();  
       Assert.Equal(homeController.ViewBag.Message, "Contains About in raw url");  
     }  

Although this would work, imagine having code like that littered around your source to facility testing.

Instead if we removed the GetUrl() virtual method from the controller:

  public ActionResult About()  
     {  
       ViewBag.Message = "Your application description page.";  
       if (Request.RawUrl.Contains("About"))  
       {  
         ViewBag.Message = "Contains About in raw url";  
       }  
       return View();  
     }  

Thats better, we can now write unit test using NSubstitute:

  public HttpContextBase MockHttpRequestBase()  
     {  
       var request = Substitute.For<HttpRequestBase>();  
       request.RawUrl.Returns(@"\About");  
       var context = Substitute.For<HttpContextBase>();  
       context.Request.Returns(request);  
       return context;  
     }  
  [Fact]  
     public void Test_Default_Message()  
     {  
       var homeController = new HomeController();  
       homeController.ControllerContext = new ControllerContext(MockHttpRequestBase(), new RouteData(), homeController);  
       homeController.About();  
       Assert.Equal(homeController.ViewBag.Message, "Contains about in raw url");  
     }