Showing posts with label Dependency Injection. Show all posts
Showing posts with label Dependency Injection. Show all posts

Tuesday, 7 January 2014

Using Dependency Injection with ASP.NET Web API Hosted on Katana

Using Katana we can build a light-weight server to host an ASP.NET application, without needing IIS or System.Web. Katana has a nice support for hosting SignalR and Web API with very few lines of code. In a previous post, we saw how to self-host SignalR using Katana. In this post, we will see how easy it is to perform dependency injection on a self-hosted Katana application.

Open Visual Studio 2013 and create a new console application. Add following NuGet packages to the application:


  • Install-Package Microsoft.AspNet.WebApi.Owin
  • Install-Package Ninject


First package gets a bunch of packages for creating and hosting Web API. The second package installs the Ninject IoC container.

Add an API Controller to the application and change the code of the controller to:

public class ProductsController : ApiController
{
    IProductsRepository repository;

    public ProductsController(IProductsRepository _repository)
    {
        repository = _repository;
    }

    public IEnumerable<Product> Get() 
    {
        return repository.GetAllProducts();
    }
}

We need to inject instance of a concrete implementation of IProductRepository. We will do this using dependency injection. You can create the repository interface and an implementation class by your own.

To perform dependency injection with Web API, the WebApiContrib project has a set of NuGet packages, including one for Ninject. But the version of Web API it requires is 4.0.30319. As we are using VS 2013, the default version of Web API is 5.0.0.0. Installing this NuGet package may result into version compatibility issues. To avoid this issue, we can build the WebapiContrib.Ioc.Ninject project using VS 2013 or we can also copy the code of NinjectResolver class from the GitHub repo and add it to the console application.

In the Owin Startup class, we need to configure Web API and also tie it with an instance of NinjectResolver. Constructor of NinjectResolver accepts an argument of IKernel type. Kernel is the object where we define the mapping between requested types and types to be returned. Let’s create a class with a static method; this method will create the kernel for us. Add a class and name it NinjectConfig. Change code of the class as:

public static class NinjectConfig
{
    public static IKernel CreateKernel()
    {
        var kernel = new StandardKernel();

        try
        {
            kernel.Bind<IProductsRepository>().To<ProductRepository>();
            return kernel;
        }
        catch (Exception)
        {
            throw;
        }
    }
}

Now all we need to do is, configure Web API and start the server. Add a class, change the name as Startup and replace the code as:
public class Startup
{
    public void Configuration(IAppBuilder app)
    {
        var config = new HttpConfiguration();
        config.DependencyResolver = new NinjectResolver(NinjectConfig.CreateKernel());

        config.Routes.MapHttpRoute("default", "api/{controller}/{id}", new { id=RouteParameter.Optional });

        app.UseWebApi(config);
    }
}


Finally, start the server in Main method:
static void Main(string[] args)
{
    string uri = "http://localhost:8080/";

    using (WebApp.Start<Startup>(uri))
    {
        Console.WriteLine("Server started...");
        Console.ReadKey();
        Console.WriteLine("Server stopped!");
    }
}


Open a browser and enter the following URL:


http://localhost:8080/api/products


You should be able to see list of products returned from the repository class.

Happy coding!

Tuesday, 2 October 2012

Injecting dependencies into SignalR hub using Unity

In one of my earlier post, I discussed on Dependency Injection with SignalR using Ninject. In this post, we will see how to do it with Unity.

We had a NuGet package available to make our work easier to work with Ninject. We don’t have such a package for Unity. The only difference is that, we need to write one more small class to make the things work.

We need to define a dependency resolver that derives from SignalR.DefaultDependencyProvider and override the methods GetService and GetServices. This implementation is shown below:

public class UnityDependencyResolver : DefaultDependencyResolver
{
        IUnityContainer container;
 
        public UnityDependencyResolver(IUnityContainer container)
        {
            if (container == null)
            {
                throw new ArgumentNullException("container", "Containet cannot be null");
            }
            this.container = container;
        }
 
        public override object GetService(Type serviceType)
        {
            return base.GetService(serviceType) ?? container.Resolve(serviceType);
        }
 
        public override IEnumerable<object> GetServices(Type serviceType)
        {
            return base.GetServices(serviceType) ?? container.ResolveAll(serviceType);
        }
}

We have to register the requested types and target types to the container as shown below:
public static class UnityIoC
{
    public static IUnityContainer Initialize()
    {
        IUnityContainer container = new UnityContainer();
        container.RegisterType<ICustomerRepository, CustomerRepository>();
        container.RegisterType<IJavaScriptMinifier, NullJavaScriptMinifier>();
        return container;
    }
}

In this case, I registered the target type for IJavaScriptMinifier as Unity fails to work without this registration. Ninject and StructureMap don’t need this type to be registered. As last step, we need to set the resolver to RouteTable.Route.MapHubs when the application starts.
public class Global : System.Web.HttpApplication
{ 
    void Application_Start(object sender, EventArgs e)
    {
        GlobalHost.DependencyResolver = new UnityDependencyResolver(UnityIoC.Initialize());
        RouteTable.Routes.MapHubs();            
    }
}

Important note: If you are using SignalR in an ASP.NET MVC project, then configure SignalR first and then ASP.NET MVC. Check SignalR wiki for more details.

Happy Coding!

Sunday, 9 September 2012

Injecting dependencies into SignalR hub using Ninject

Hub is the key component for SignalR on the server. We put the key functional logic in the hub class. So, it is very much possible that we will have to access database or files on the server from the hub class. This dependency may make the hub less testable.

To avoid such difficulties, we will have to implement Dependency Inversion Principle. The hub has to contain an abstract reference of the dependency. An object of the concrete implementation of the abstract type will be injected into the hub using an Inversion of Control (IoC) container. This makes the hub less dependent on the concrete implementation, hence testable in isolation. Inversion of Control is a huge topic to discuss. If you are new to IoC, read this nice post by Joel Abrahamsson. If you have a subscription to Pluralsight, watch the course on Inversion of Control by John Sonmez.

In .NET, we inject the dependencies into a class using a library known as Inversion of Control container or IoC container. There are several implementations of IoC containers. Some of them are: 

  • Ninject
  • Unity
  • Structure Map
  • Castle Windsor
  • MEF

Usage of the IoC containers differs from each other. Before using any of these libraries, we have to learn and understand the syntax using which we configure the types and the way in which we have to resolve them.

SignalR has a dependency resolver class (SignalR.DefaultDependencyResolver). This class is used by the SignalR library to resolve all the dependencies. You may check the source code on GitHub to know what this class does. To inject the dependencies in our application, we have to write a class that derives from the DefaultDependencyResolver class. We have to override the GetService and GetServices methods. The logic in these methods is responsible to accept the abstract type and return an object of the concrete implementation.


For example, say the hub class talks to a database. In enterprise applications, we use the Repository Pattern to perform database operations. Say ICustomerRepository is a repository interface and CustomerRepository is the concrete implementation of this interface.
public interface ICustomerRepository
{
 void AddCustomer(Customer customer);
 void ModifyCustomer(Customer customer);
 IEnumerable<Customer> GetCustomersByDepartment(string departmentId);
}
public class CustomerRepository : ICustomerRepository
{
 //concrete implementations of the methods
} 

Following snippet shows an incomplete implementation of a Hub using the above repository:
public class CustmerHub : Hub
{
 ICustomerRepository repository;
 public CustmerHub(ICustomerRepository repository)
 {
  this.repository = repository;
 }
 …
}

An object of CustomerRepository type has to be injected into the CustomerHub from an external agent. Add the NuGet package for Ninject to the application.


Now we need to create our own dependency resolver by extending DefaultDependencyResolver. Following is the implementation for Ninject:
public class NinjectDependencyResolver:DefaultDependencyResolver
{
    private readonly IKernel _kernel;
 
    public NinjectDependencyResolver(IKernel kernel)
    {
        if (kernel == null)
        {
            throw new ArgumentNullException("kernel");
        }
 
        _kernel = kernel;
    }
 
    public override object GetService(Type serviceType)
    {
        var service = _kernel.TryGet(serviceType) ?? base.GetService(serviceType);
        return service;
    }
 
    public override IEnumerable<object> GetServices(Type serviceType)
    {
        var services = _kernel.GetAll(serviceType).Concat(base.GetServices(serviceType));
        return services;
    }
}

We have to configure requested types and target types so that Ninject will be able to return the right objects when they are requested. Following class does this for us:
public static class NinjectIoC
{
    public static IKernel Initialize()
    {
        IKernel kernel = new StandardKernel();
        kernel.Bind<ICustomerRepository>().To<CustomerRepository>();
        kernel.Bind<RequestedType>().To<TargeTtype>();
        return kernel;
    }
}

Finally, we need to set the resolver to RouteTable.Route.MapHubs when the application starts.
public class Global : System.Web.HttpApplication
{
    void Application_Start(object sender, EventArgs e)
    {
        // Code that runs on application startup
        GlobalHost.DependencyResolver = new NinjectDependencyResolver(NinjectIoC.Initialize());
        RouteTable.Routes.MapHubs();
    }
}

With this step, we have set the dependency resolver to SignalR. Whenever it needs to resolve a dependency, the control will be passed to NinjectDependencyResolver to create the object.

Important note: If you are using SignalR in an ASP.NET MVC project, then configure SignalR first and then ASP.NET MVC. Check SignalR wiki for more details.

Happy coding!