My Adventures in Coding

March 27, 2013

C# – Using Unity for Dependency Injection in an ASP.NET MVC 4 Web API

Filed under: .NET,c#,MVC,REST — Brian @ 11:27 pm
Tags: , , ,

When I created my first REST API since I started working with MVC 4 Web API, immediately I wanted to figure out how to handle dependency injection. When I had previously worked in Java I used Spring, in Scala I used Google Guice, and so now I was on the hunt for another dependency injection tool. There are several options out there, such as Spring .NET and also Ninject, however for now we decided to go with Unity because of it’s simple setup and maturity.

With MVC 4 Web API the application creates an instance of the controller class whenever a REST call is made. So for example if you have the REST endpoint /cars it will create an instance of the controller CarsController to service the request. Now, this all works fine until you change the constructor on CarsController to take a parameter. Once you do this, you will need a dependency injection framework to handle knowing how to resolve the dependencies for CarsController when one is being created. So let’s use this as our example.

Note: For this example I am using:
Visual Studio 2012 Express Web and version 2.1.505.2 of the Unity NuGet package.

Now, in Visual Studio 2012 NuGet is built right in, so no need to install the NuGet Plugin anymore (Woohoo!)

Step 1 – Create a new Web API Project

Create a new Web API project in Visual Studio:

  • File -> New Project
  • Installed -> Templates -> Visual C# -> Web
  • Give the project the name: UnityExample
  • Click “OK”
  • Select Project Template -> Web API
  • Click “OK”

That’s all! Now you have a new Web API project called UnityExample.

Step 2 – Install Unity NuGet Package

For installing NuGet packages you can use either the GUI tool or the console.

To use the Package Manager Console tool:

  • To open the console: Tools -> Library Package Manager -> Package Manager Console
  • Now at the console prompt enter the command: Install-Package Unity

Now, if you prefer to use the GUI tool:

  • In Solution Explorer, right click on the solution and select Manage NuGet Packages for Solution
  • Ensure Online is selected, then in the search box type Unity
  • The Unity package will be displayed at the top of the list then click Install

Step 3 – Create an IOC (Inversion of Control) Container

You will need to create an IOC container that impelements IDependencyResolver. I did not write my own, I got this code from here.

using System;
using System.Collections.Generic;
using System.Web.Http.Dependencies;
using Microsoft.Practices.Unity;

namespace UnityExample
{
    // This code is from:
    // http://www.asp.net/web-api/overview/extensibility/using-the-web-api-dependency-resolver
    // The website also has a detailed explanation of how to setup dependency injection

    public class ScopeContainer : IDependencyScope
    {
        protected IUnityContainer container;

        public ScopeContainer(IUnityContainer container)
        {
            if (container == null)
            {
                throw new ArgumentNullException("container");
            }
            this.container = container;
        }

        public object GetService(Type serviceType)
        {
            if (container.IsRegistered(serviceType))
            {
                return container.Resolve(serviceType);
            }
            else
            {
                return null;
            }
        }

        public IEnumerable<object> GetServices(Type serviceType)
        {
            if (container.IsRegistered(serviceType))
            {
                return container.ResolveAll(serviceType);
            }
            else
            {
                return new List<object>();
            }
        }

        public void Dispose()
        {
            container.Dispose();
        }
    }

    class IoCContainer : ScopeContainer, IDependencyResolver
    {
        public IoCContainer(IUnityContainer container)
            : base(container)
        {
        }

        public IDependencyScope BeginScope()
        {
            var child = container.CreateChildContainer();
            return new ScopeContainer(child);
        }
    }
}

Step 4 – Create a new class called NameService.cs

The following class with be the dependency that we will inject into our new controller.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace UnityExample
{
    public class NameService
    {
        private string _myName;

        public NameService(string myName)
        {
            _myName = myName;
        }

        public string GetMyName()
        {
            return string.Format("My name is: {0}", _myName);
        }
    }
}

Step 5 – Create a new Controller called NameController which requires NameService as a constructor parameter

To create the new controller NameController:

  • Right click on the Controllers folder and select Add -> Controller
  • Enter Controller name: NameController
  • From the Template drop-down select Empty API controller

Now enter the following code in your new NameController class:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web.Http;

namespace UnityExample.Controllers
{
    public class NameController : ApiController
    {
        private NameService _nameService;

        public NameController(NameService nameService)
        {
            _nameService = nameService;
        }

        public string Get()
        {
            return _nameService.GetMyName();
        }
    }
}

Step 6 – Setup Dependency Injection with Unity in Global.asax.cs

Now the final step is to create an instance of NameService and tell Unity to use that instance anytime an instance of NameController is created.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Http;
using System.Web.Mvc;
using System.Web.Optimization;
using System.Web.Routing;

// Add usings for Unity and Controllers
using Microsoft.Practices.Unity;
using UnityExample.Controllers;

namespace UnityExample
{
    public class WebApiApplication : System.Web.HttpApplication
    {
        protected void Application_Start()
        {
            AreaRegistration.RegisterAllAreas();
            WebApiConfig.Register(GlobalConfiguration.Configuration);
            FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
            RouteConfig.RegisterRoutes(RouteTable.Routes);
            BundleConfig.RegisterBundles(BundleTable.Bundles);

            // Create a new Unity dependency injection container
            var unity = new UnityContainer();

            // Register the Controllers that should be injectable
            unity.RegisterType<HomeController>();
            unity.RegisterType<NameController>();

            // Register instances to be used when resolving constructor parameter dependencies
            unity.RegisterInstance(new NameService("It Worked!!!"));

            // Finally, override the default dependency resolver with Unity
            GlobalConfiguration.Configuration.DependencyResolver = new IoCContainer(unity);
        }
    }
}

Step 7 – Now let’s run the app and see that it worked!

Now run the app: Debug -> Start Without Debugging or (Ctrl F5).

When a browser opens, you will see the usual default home page for a .Net MVC 4 Web API application.

Now add the following to your url: /api/name. For example: http://localhost:62283/api/name.

Note: Remember the default path for all ApiControllers in Web API always starts with /api.

You should see the following output:

<string>My name is: It Worked!!!</string>

That is all!

Now that you have a working example, I recommend you read more about how it works in the following article:

Using the Web API Dependency Resolver

September 29, 2011

Scala – Hello World REST API with Scalatra and Simple Build Tool

Filed under: REST,Scala,Simple Build Tool — Brian @ 9:00 pm
Tags: , ,

I am new to Simple Build Tool and also to building REST APIs in Scala. Mostly I have been using Python with Bottle for REST APIs up until this point. For our current project our REST API will be written in Scala, so I wanted to try out Scalatra. They have excellent documentation and examples, however they assume you have a good understanding of Simple Build Tool (known as sbt or xsbt). I will walk you through running the Scalatra example with Simple Build Tool, assuming you are using it for the first time.

The example we are using is the main example from Scalatra’s website http://www.scalatra.org/.

Get the example application

Clone the Scalatra Hello World REST API example application using git.

git clone http://github.com/scalatra/scalatra-sbt-prototype.git

Download Simple Build Tool

Download version 10 (used for the Scalatra example) of Simple Build Tool into the “scalatra-sbt-prototype” directory.

cd scalatra-sbt-prototype
wget http://typesafe.artifactoryonline.com/typesafe/ivy-releases/org.scala-tools.sbt/sbt-launch/0.10.0/sbt-launch.jar

NOTE: If you use version 0.11.0 of Simple Build Tool with this example you will get the error: “sbt.ResolveException: unresolved dependency: com.github.siasia#xsbt-web-plugin_2.9.1;0.1.0-0.11.0: not found”.

Create a script to run Simple Build Tool

In the “scalatra-sbt-prototype” directory create a file called “sbt.sh” containing the following text:

java -Xmx512M -XX:MaxPermSize=128M -jar `dirname $0`/sbt-launch.jar "$@"

Also, make sure the script is executable:

chmod 755 sbt.sh

NOTE: setting MaxPermSize is important. This example will sometimes throw a “Error during sbt execution: java.lang.OutOfMemoryError: PermGen space” error if the PermGen memory size has not been increased.

Run the example

In the “scalatra-sbt-prototype” folder execute the sbt script:

./sbt.sh

Once the Simple Build Tool prompt has opened, you can now start the web app which uses Jetty:

jetty-run

Confirm it is working

If everything went as planned, you should be able to navigate to http://localhost:8080/ and see “Hello World”.

That’s all!

January 2, 2011

Creating a REST API in Python using Bottle and MongoDB

Filed under: MongoDB,Python,REST — Brian @ 10:15 pm
Tags: , , , , , ,

I have been using Bottle and MongoDB for a REST API project for almost a year now. I frequently get asked the question “Bottle, what is Bottle, I have never heard of it” and “Ok, I have read the Bottle tutorial, it is simple, but how do I use Bottle with MongoDB?”. So I decided to write up a simple “Getting Started” tutorial for my friends curious about these technologies.

Prerequisites: Python 2.7 or higher

Setup MongoDB

MongoDB is a document store, a schema less database. What makes MongoDB unique (and why we decided to use it) is that MongoDB is a hybrid document store. What this means is that MongoDB offers the freedom of storing data in a schema less fashion, while still providing a flexible query syntax that will make anyone familiar with SQL feel comfortable.

You will need to download the latest version of MongoDB from the downloads page. Let’s download MongoDB and get it up and running.

First, setup the data folder. By default MongoDB stores all data files in the folder /data/db, so let’s create the folder:

sudo mkdir -m 777 -p /data/db

Download MongoDB:

wget http://fastdl.mongodb.org/osx/mongodb-osx-x86_64-1.6.5.tgz
tar -zxvf mongodb-osx-x86_64-1.6.5.tgz

Now let’s start MongoDB:

cd mongodb-osx-x86_64-1.6.5/bin
./mongod

NOTE: We have not created a database, or even a collection (you can think of a collection as a schema free table). When a document is being saved, MongoDB will lazily create the collection if it does not exist, and if the database does not exist, it will also create the database. It’s just that simple!

If you would like a more detailed introduction to using MongoDB, the query syntax, etc, please refer to my previous post: Getting Started with MongoDB

Setup Bottle

Bottle is a very simple Python web framework that is contained in a single Python file (bottle.py). We have been using Bottle for creating REST APIs and have been very impressed with just how easy it is to use.

Install the Bottle package into your Python site-packages folder:

pip install bottle

Setup PyMongo

PyMongo is a library for interacting with MongoDB from a Python application. This package bridges the gap between Bottle and MongoDB.

Install the PyMongo package into your Python site-packages folder:

pip install pymongo

Putting it all together: A Simple REST API

Now, on to the fun stuff! Let’s write a simple Python REST API, with a GET and a PUT, using Bottle, that allows us to save and retrieve documents to and from MongoDB using PyMongo.

Create a new file:

touch myrestapi.py

Cut and paste the following code:

import json
import bottle
from bottle import route, run, request, abort
from pymongo import Connection

connection = Connection('localhost', 27017)
db = connection.mydatabase

@route('/documents', method='PUT')
def put_document():
	data = request.body.readline()
	if not data:
		abort(400, 'No data received')
	entity = json.loads(data)
	if not entity.has_key('_id'):
		abort(400, 'No _id specified')
	try:
		db['documents'].save(entity)
	except ValidationError as ve:
		abort(400, str(ve))
	
@route('/documents/:id', method='GET')
def get_document(id):
	entity = db['documents'].find_one({'_id':id})
	if not entity:
		abort(404, 'No document with id %s' % id)
	return entity

run(host='localhost', port=8080)

Start the application:

python myrestapi.py

Using our new REST API

Now let’s try saving and retrieving some documents. If you do not have a preferred REST client handy and are using the Google Chrome browser, you should try the extension Simple REST Client.

Save a document
  • Open up your favorite REST client and point it at the following URL:
  • Now select PUT and enter the following data:
    • {"_id": "doc1", "name": "Test Document 1"}

NOTE: The primary key of a document in a MongoDB collection is always the field “_id”. If you specify an “_id” in your document it will be used, if you do not, MongoDB will generate a unique id.

Retrieve a document
  • In your REST client enter the URL for retrieving the document we just saved:
  • Now select GET and you should see the same document returned:
    • {"_id": "doc1", "name": "Test Document 1"}

That is it! You now have a basic, working, REST API written in Python using Bottle and MongoDB!

July 5, 2009

Java – REST APIs and Thread Safety

Filed under: Java,REST — Brian @ 7:26 pm
Tags:

In my current job, a few months ago we ran into some strange issues on production. Customers were complaining that sometimes they would receive incorrect data when accessing our REST APIs. We were never able to reproduce the issue and the strange results customers were receiving seemed entirely random. Until one day while a member of our team was accessing a REST API at the same time as a customer. As a result the customer received the employee’s information! After this discovery we found that when accessing a REST call in our system concurrently with different parameters we were consistently able to reproduce the problem the customer was complaining about. Yep, we had classes that were not thread safe and needed to be fixed!

The Bug

In our case the thread safety issue was related to the use of local variables inside a class declared as a singleton in our Spring configuration. The issue was a race condition between when the lookup parameter (e.g., customerId) was set and when it was used to lookup a requested value (e.g., email). Take a look at this example class:

public class CustomerInfo {
    int customerId;

    public void setCustomerId(int customerId) {
        this.customerId = customerId;
    }

    public String getEmail() {
        return customerRepository.getEmail(customerId);
    }
}

Let’s say we have two customers placing an order:
Customer 1: has an email address of jsmith@nowhere.com
Customer 2: has an email address of jdoe@nowhere.com

Now we have two callers accessing our REST API at the same time so two threads are using our CustomerInfo class:

  • Thread A: setCustomerId(1) – customerId=1
  • Thread B: setCustomerId(2) – customerId=2
  • Thread A: getEmail() – customerId=2 so email jdoe@nowhere.com is returned
  • Thread B: getEmail() – customerId=2 so email jdoe@nowhere.com is returned

The Fix

So even though the code calling the getEmail() method was calling it immediately after setting the customerId with the setCustomerId() method, if two threads were running at the same time the chances of the customerId being updated by one thread and affecting the results of another were very likely. There was no reason why we needed to set a customerId value in the class, this was just extra code that was not needed. So removing unnecessary code and fixing our thread safety issue ended up being connected:

public class CustomerInfo{
    public String getEmail(int customerId) {
        return customerRepository.getEmail(customerId);
    }
}

The way we were able to find and track down this concurrency bug was by writing a concurrency test first.

A Simple Concurrency Test

A concurrency test for a REST call does not have to be anything complicated. Just take a REST call you want to test and write a test following this basic outline:

  • One REST call to test
  • A list of valid parameters to use with that REST call and an expected value for each parameter.
  • This expected value is used to check that the request was successful (e.g., parameter CustomerID=2938 returns Email=johnsmith@gmail.com).
  • Pool of threads, each calling the REST call for each of the parameters in the list.
  • Verify every REST call in each thread returns the expected value.

Now run the test and if any of the REST calls return data that does not match the expected value, you know you have some code that is not thread safe. Now that you have this failing test in place you can proceed with finding and fixing your thread safety issues!

February 9, 2009

Where is the maven release for Jersey-Spring 1.0.1?

Filed under: REST — Brian @ 1:46 pm
Tags: ,

Just before the Jersey 1.0.1 release was made, the module structure was changed from

com.sun.jersey
to
com.sun.jersey.contribs

This caught us recently when we wanted to reference version 1.0.1 in our pom.xml file. We could only find 1.0.1-SNAPSHOT at:

http://download.java.net/maven/2/com/sun/jersey/jersey-spring/

Then we realized we needed to be using:

http://download.java.net/maven/2/com/sun/jersey/contribs/jersey-spring/

So we updated our pom.xml file dependency to the following:


<dependency>
<groupId>com.sun.jersey.contribs</groupId>
<artifactId>jersey-spring</artifactId>
<version>1.0.1</version>
</dependency>

I hope this post helps you out!

Create a free website or blog at WordPress.com.