Showing posts with label Katana. Show all posts
Showing posts with label Katana. 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!

Monday, 30 December 2013

Self-Hosting ASP.NET SignalR Using Katana

With the recent release of ASP.NET, Microsoft added a new component, Katana. It is an implementation of OWIN (Open Web Interfaces for .NET) that provides a light weight alternative to create a .NET server quickly without needing any of the ASP.NET components or IIS. The server can be composed anywhere, even on a simple Console based application. For more information on Katana, read the excellent introductory article by Howard Dierking.

The project templates of ASP.NET that come with Visual Studio 2013 have some pieces of Katana also installed, as we saw some of them in my post on Identity system. It is used there to make the identity system available for across all flavours of ASP.NET.

Katana made the process of self-hosting ASP.NET Web API and SignalR very easier with its simple interface. Any Katana based application needs a startup class to kick the things off. We can perform any global configuration in this class. It includes hub route mapping in SignalR or API controller routing in Web API.

Let’s build a simple console-hosted SignalR application using Katana. Create a console application using Visual Studio 2013 and install the following NuGet package on this project:


Install-Package Microsoft.AspNet.SignalR.SelfHost


This package installs all the dependencies required to write and publish a SignalR application on a non-web based environment. Add a new class to the project; name it Startup and add the following code to it:

public class Startup
{
    public void Configuration(IAppBuilder app)
    {
        app.MapSignalR();
    }
}

The configuration method is used comparable to Application_Start event in Global.asax, it gets called at the beginning of the application. As we see, SignalR routes are mapped in the configuration method. We need to start the server in the Main method of the Program class. Add following code to the Main method:
static void Main(string[] args)
{
    string uri = "http://localhost:8080/";

    using (WebApp.Start<Startup>(uri))
    {
        Console.WriteLine("SignalR server started, start sending requests");
        Console.ReadKey();
        Console.WriteLine("Server stopped!");
    }
}

As there is no web server to host our application, we need to specify a port number where the server has to keep running. The generic static method WebApp.Start is called to start the server; it calls the Configuration method defined above. The server would stop once the console application stops running.

Let’s create a boring hello-world kind of hub. Following is a hub that takes name of a person and returns a greeting message with current time stamp:

public class HelloWorldHub : Hub
{
    public void Greet(string name) 
    {
        Console.WriteLine("Got a request from: {0}", name);
        string message= string.Format("Hello, {0}. Greeted at: {1}",name,DateTime.Now.ToString());
        Clients.All.acceptGreeting(message);
    }
}

Run the console application, you should be able to see the following message:

Let’s quickly create a console client to test if the server is able to push messages to the client. Create another console application and add the following NuGet package to it:


Install-Package Microsoft.AspNet.SignalR.Client


Add following code to the Main method:

static void Main(string[] args)
{
    var hubConnection = new HubConnection("http://localhost:8080/");
    var hubProxy = hubConnection.CreateHubProxy("HelloWorldHub");
    hubProxy.On<string>("acceptGreeting", message => {
        Console.WriteLine("Received from server: " + message);
        Console.WriteLine("\n\nPress any key to exit.");
    });

    Console.WriteLine("Establishing connection...");
    hubConnection.Start().Wait();
    Console.WriteLine("Sending request to hub...");
    hubProxy.Invoke("Greet", "Ravi").Wait();

    Console.ReadLine();
    hubConnection.Stop();
}

Run the client application, you should be able to see the following output:



Happy coding!