OpenRasta

Implementing Hypermedia Links with OpenRasta

Posted in OpenRasta, REST on July 25th, 2012 by Emily Skitek – 2 Comments

For this month’s innovation time, I wanted to experiment with implementing hypermedia links using OpenRasta. Links are used in REST to tell the client how to transition from one state to the next. This is something we don’t do (yet) in our API. It’s considered to be a feature of a level 3 REST API.

Martin Fowler explains: ”The point of hypermedia controls is that they tell us what we can do next, and the URI of the resource we need to manipulate to do it. Rather than us having to know where to post our appointment request, the hypermedia controls in the response tell us how to do it…. One obvious benefit of hypermedia controls is that it allows the server to change its URI scheme without breaking clients… A further benefit is that it helps client developers explore the protocol. The links give client developers a hint as to what may be possible next.”

My first decision was on where to put the links – that is, how to deliver them to the client. There seemed to be a couple of options:
  1. Put the links in the response LinkHeader
  2. Put the links in the body of the response. Something like:

<order>
    <id>156</id>
    <status>Pending Payment</status>
    <items>
        <sku>12345</sku>
        <quantity>1</quantity>
    </items>
    <links>
        <link rel="order" url="http://api.mycompany.com/orders/156" />
        <link rel="invoice" url="http://api.mycompany.com/payments/156" />
        <link rel="payment" url="http://api.mycompany.com/invoices/156" />
    </links>
</order>
There didn’t seem to be a clear recommendation on which way to go. Some people recommend option (1) because you can get to the links without having to parse the response body. However, I ended up going for option (2), because option (1) would get messy/unwieldy in scenarios where a list of items was returned in the response and you wanted to associate links with specific items in the list. To put it another way, option 1 would work well for response-level links, but not so well for resource-level links. Thanks to my colleagues Greg and Matt for the opinions/insight on this!

To spike this, I created a very simple OpenRasta app that has a single API method for creating a basket. It actually doesn’t do anything except for to new up a BasketResource and return it in the OperationResult’s ResponceResource, but that’s sufficient for our purposes.

Before returning the BasketResource, the handler sets a “self” LinkResource on the newly created BasketResource using OpenRasta’s UriResolver.CreateUriFor method, which handily constructs the link based on the routing you’ve defined in the ConfigurationSource. The handler also sets the “RedirectLocation” on the OperationResult, which sets the Location header on the response.

There are several OpenRasta extension methods that make it easier to create URIs for resources (ex: resource.CreateUri()), but these were problematic to unit test so I settled on the slightly more cumbersome (but testable) CreateUriFor method in the code sample below. The logic for constructing links should ultimately be pushed out of the BasketHandler and into another object that only is responsible for making links, but I haven’t gotten around to that refactoring bit yet.

The IUrlResolver and ICommunicationContext dependencies on BasketHandler are internal OpenRasta objects that are automatically resolved for your pleasure.
using System;
using System.Collections.Specialized;
using OpenRasta.Api.Basket.Resources;
using OpenRasta.Web;

namespace OpenRasta.Api.Basket.Handlers
{
    public class BasketHandler
    {
        private readonly IUriResolver _uriResolver;
        private readonly ICommunicationContext _communicationContext;

        public BasketHandler(IUriResolver uriResolver, ICommunicationContext communicationContext)
        {
            _uriResolver = uriResolver;
            _communicationContext = communicationContext;
        }

        [HttpOperation(HttpMethod.POST)]
        public OperationResult Create()
        {
            var basketResource = new BasketResource { Id = 1 };
            var getBasketUri = CreateGetBasketUri(basketResource);
            var selfLink = CreateSelfLink(getBasketUri);
            basketResource.SelfLink = selfLink;
            return new OperationResult.Created
                    {
                        RedirectLocation = getBasketUri,
                        ResponseResource = basketResource
                    };
        }

        private static LinkResource CreateSelfLink(Uri getBasketLink)
        {
            return new LinkResource{ Relation = "self", Uri = getBasketLink.AbsoluteUri };
        }

        private Uri CreateGetBasketUri(BasketResource basketResource)
        {
            return _uriResolver.CreateUriFor(
                _communicationContext.ApplicationBaseUri,
                basketResource.GetType(),
                null,
                new NameValueCollection { { "id", basketResource.Id.ToString() } }
                );
        }
    }
}
One question I had, as I was thinking about other links that could be added in the above example, was: How does the client know which http method to use on a URI? For example, what if I included another link to cancel the basket?
<link rel="cancel" uri="http://myapi.com/basket/123" />

This is the same uri as the “get” uri used to retrieve the basket – the only difference is that to “cancel”, the client must use the DELETE method (instead of GET). I found this same question asked on StackOverflow. Some said that the API documentation should provide this sort of detail, but someone else recommended including another attribute on the link to specify the method.

One of my colleagues, Phil, also brought up the point that you could use the OPTIONS method to tell the client which http methods can be used on a resource. However, the down-side to this is that the client would have to make an additional API call to find out this information.

To me, the attribute link approach seems the most user-friendly (and discoverable) option – why force the client to make another API call or make the developer consult API documentation for something that could easily be specified within the link itself? In the above example, it might look like:
<link rel="cancel" method="delete" uri="http://myapi.com/basket/123" />

I haven’t implemented this bit of functionality yet, but it should be easy enough to do.

The full source is here on github.

Getting started with web applications on Mono

Posted in API, Development, How To, OpenRasta on February 17th, 2012 by Hibri Marzook – 2 Comments

 

I’ve started to explore mono, with a view to moving some of our web applications to Linux. Used MonoDevelop  on OSX to  spike a simple HttpHandler to return a response.  I was more interested in how the hosting and deployment story worked with mono.

This is a little list of things I discovered as I went along.

http://www.mono-project.com/ASP.NET has  list of the hosting options available.  Went with the Nginx option.  Mono comes with xsp, which is useful for local testing.

Running a simple web application

To run xsp  /usr/bin/xsp –port 9090 –root  <path to your application>, and the application will be available on http://localhost:9090

 

To install Nginx on OSX,  get Homebrew.  And then simply  sudo brew install nginix

Follow the instructions here http://www.mono-project.com/FastCGI_Nginx to configure Nginix to work with Mono’s FastCGI server.

On OSX, the Nginix configs can be found in /usr/local/etc/nginx/nginx.conf

This is the configuration I tried for my testing,

In /usr/local/etc/nginx/nginx.conf

server{
   listen 80;
   server_name localhost;
   access_log /var/log/nginx/localhost_mono_access.log;
   location / {
        root /Users/hibri/Projects/WebApp/;
        index default.aspx index.html;
        fastcgi_index default.aspx;
        fastcgi_pass 127.0.0.1:9000;
        include /usr/local/etc/nginx/fastcgi_params;
   }
}

Add the following lines to /usr/local/etc/nginx/fastcgi_params

 fastcgi_param  PATH_INFO          "";
 fastcgi_param  SCRIPT_FILENAME    $document_root$fastcgi_script_name;

 

Start Nginx.

Start the Mono FastCGI server

fastcgi-mono-server2
     /applications=localhost:/:/Users/hibri/Projects/WebApp/ /socket=tcp:127.0.0.1:9000

And the application is available on http://localhost

Web Frameworks

We use OpenRasta for the services I want to run on Linux. OR didn’t work out of the box. This is something I’ll be exploring in the next few days.

Tried ServiceStack too, and was able to get one our projects (https://github.com/gregsochanik/basic-servicestack-catalogue) working on Mono as is.  Nancy is next on the list.

OpenRasta and CastleWindsor Concurrency Issue

Posted in Development, OpenRasta, Search, SolrNet on January 12th, 2012 by gregsochanik – 3 Comments

A couple of months ago we discovered an issue in the 2.0.3 version of the OpenRasta project.

Heisenbug

To cut a long story short we noticed a Heisenbug in our search endpoints, which use OpenRasta as a business layer between our Api and the Apache Solr search engine.

Every now and then, with no apparent pattern, we would see a series of errors being thrown from Castle.Windsor. This was the error we saw:

System.IndexOutOfRangeException: Index was outside the bounds of the array.
     at System.Collections.Generic.List`1.Add(T item)
     at Castle.MicroKernel.Handlers.AbstractHandler
        .EnsureDependenciesCanBeSatisfied(IDependencyAwareActivator activator)
Checking the event logs on the live servers we noticed that this error always corresponded exactly with an application pool recycle. This then led us to think that the issue must be to do with application start-up.

DependencyResolverAccessor

OpenRasta has a concept of an IDependancyResolverAccessor, which exposes an interface allowing you to implement your own choice of Dependency Injection framework to set up your dependencies. OpenRasta can then resolve instances that have been added to the container at run time in the normal way.

Our DI framework of choice for this project was Castle.Windsor, which is a very mature solution, and also integrates very well with SolrNet. The stack trace for the error led us to the WindsorDependencyResolver, which then led us through to Castle Windsor’s own internal dependency store which uses a generic List<T>. It turns out that .NET generic Lists are not thread safe.

The DependencyResolver is set up as a Singleton, and therefore is only ever called once, at the start of the application. We then deduced that what must be happening is that at application startup, if a large amount of requests come through at the same time, they can access the same List<T>. This in turn can throw the backing array out of sync with the size of the list, resulting in the IndexOutOfRangeException we saw.

To illustrate this, I was able to write an Integration Test that used Threading to fire a large number of concurrent requests at it, each one newing up an instance of WindsorDependencyResolver to emulate application startup.

The Fix

To fix the issue, we needed to use the double-check locking pattern around the resolvers internal container. This ensures that there is indeed only ever one Container set up even if multiple threads access this on application start-up.

private static volatile IWindsorContainer _windsorContainer;
private static readonly object _synchRoot = new object();
public WindsorDependencyResolver(IWindsorContainer container)
{
    if (_windsorContainer == null) {
        lock (_synchRoot) {
             if (_windsorContainer == null) {
                   _windsorContainer = container;
             }
        }
    }
}
Note the use of the C# volatile keyword used to enforce read/write barriers around all access of the singleton IWindsorContainer. This removes the need to use .NETs Thread.MemoryBarrier().

This has been in production for 2 months and thankfully we’ve seen no repeat of the error!

OpenRasta is opening up to the community

Posted in OpenRasta on January 11th, 2012 by Antony Denyer – 1 Comment

Last Thursday a few of us from 7digital had a meet up with Sebastien Lambla author of OpenRasta.

As some of you may know we’re been writing all our new API endpoint using OpenRasta, we have a vested interested in ensuring the success of this project and as such are responding to the rallying cry with gusto.

So what’s going to happen? Essentially 7digital, along with Huddle and Neil Mosafi, will jumping on board to help out with development and maintenance of OpenRasta 2.x. Short term goals are to help people get started with OpenRasta. At the moment it’s not particularly easy to get going with the 2.1 code. The first thing to get up and running with is a build server, this is something that 7digital will be taking responsibility for. Our first aim is to build OpenRasta and publish _latest binaries with every push and make those binaries available in OpenWrap, NuGet and as binary downloads.

We’re really looking forward to working with everyone on OpenRasta and can’t wait to get stuck in.

Creating a basic catalogue endpoint with ServiceStack

Posted in OpenRasta, REST, ServiceStack, Uncategorized on October 17th, 2011 by gregsochanik – 1 Comment

Overview

Servicestack is a comprehensive web framework for .NET that allows you to quickly and easily set up a REST web service with very little effort. We already use OpenRasta to achieve this same goal within our stack, so I thought it would be interesting to compare the two and see how quickly I could get something up and running.

The thing that most interested me initially about ServiceStack was the fact that it claims out of the box support for Memcached, something we already use extensively to cache DTOs, and Redis, the ubiquitous NoSql namevaluecollection store.

Getting cracking

I set myself the task of creating a basic endpoint for accessing 7digital artist, release and track details. Whilst taking advantage of ServiceStack’s ability to create a listener from a console window so I didn’t have to waste time attempting to set it up via IIS:

class Program {
      static void Main(string[] args)
      {
             var appHost = new AppHost();
             appHost.Init();
             appHost.Start("http://localhost:2211/");
             Console.Read();
       }
}
As you can see this couldn’t be simpler. Whilst the thread is running, it will listen at localhost on port 2211 for incoming requests.

AppHost

Every ServiceStack implementation starts with the concept of an AppHost, which is a catch all class that exposes the initial setup of your service. For a console app based HttpListener setup It relies on you overriding the AppHostHttpListenerBase.Configure() method, which offers up a Container for access to the built in IOC. Funq is the weapon of choice in Service Stack.

It seems a shame that Service Stack doesn’t abstract away the responsibility of the IOC, allowing the developer the case to write their own IOC implementation as you can with OpenRasta, but the emphasis with ServiceStack is on speed (both of performance and setup) and Funq is perfectly adequate.

Routes

The AppHost is where it is suggested that you set up the concept of Routes, which like with the ConfigurationSource in OpenRasta, you set up your Resource – UriTemplate relationship:

Routes
    .Add<Artist>("/artist/details")
    .Add<Artist>("/artist/details/{Id}")
    .Add<Release>("/release/details")
    .Add<Release>("/release/details/{ReleaseId}");
As with OpenRasta, the resource is represented by a simple DTO. In exactly the same way (via the KeyedValueBinder attribute in OR) your DTO represents the incoming request parameters, or POST request representation of your resource.

Services

The actual service itself (the equivalent of the Handler in OR) is where the request gets processed. There are a couple of ways you can accomplish this, but I opted for the documented method of deriving from the RestServiceBase<TResource> class. From within here you can the override a set of “On” methods which ServiceStack routes the call through to depending on the verb used, for example:

public override object OnGet(Artist request) {
    // Service logic here
}
Those familiar with OpenRasta will recognise a similar concept in setting up of Handlers, but with a few subtle but important differences. OpenRasta successfully decouples the concept of a handler from your implementation by allowing you to tie it to a resource, which from a clean code perspective I prefer.

OpenRasta also more importantly does not assume that you will be implementing all http verbs within a handler, and returns a valid 405 Method Not Allowed if you have not implemented that method for a service.

IOC implementation

ServiceStack’s default Funq works very well and you can opt for both constructor injection or property injection. Ctor injection is our (and should also be your) preferred way of achieving this, and Funq handled this perfectly. As mentioned earlier, you set up your container within the AppHost. You can then use the familiar Register<TInterface>(ConcreteInstance) to set up your dependencies..

MediaTypes / Features

ServiceStack’s great selling point is the ability to set up a “verticle slice” of a site incredibly quickly, and this it does without fail. Once I had my resource DTOs, service and AppHost set up I was able to access it immediately. It also supports many different media types out of the box, which can be turned off and on within the AppHost like so:
SetConfig(
   new EndpointHostConfig
   {
      EnableFeatures = Feature.All.Remove(Feature.All)
      .Add(Feature.Xml | Feature.Json | Feature.Html),
   }
);

Caching and ReDis

ServiceStack is true to its word that it supports a caching layer out of the box, and it is really easy to set up. It comes with its own MemoryCacheClient which works well as a basic .NET IDictionary implementation of a cache. It supports TTLs but not sure about LRU (least recently used) or other caching strategies. Each Cache class implements the ICacheClient class, and you just set up the dependancy in the AppHost in the normal way. You can then inject it into your caching service as normal. ReDis works in exactly the same way, and it does just work. I was very impressed with it’s implementation. It would have been nice to test its Memcached setup, but that didn’t come with the latest release, it’s only available within the latest cut from github. I downloaded it, but due to some initial setup issues ran out f time before I could play with it. It’s essentially an adapter around the Enyim library which we already use for our Memcached setup.

Pipeline vs ResponseFilters

OpenRasta allows you the ability to “hook into” various stages of its pipeline process outlined here. I wanted to see if ServiceStack did the same and I got very excited when I saw the concept of ResponseFilters, which again are set up in the AppHost. Sadly I ran out of time on this, I wanted to try and implement a “catch all” way of dealing with my http response codes issue as mentioned above, but this could be something I investigate further at a later date.

HttpStatusCodes

My biggest issue with ServiceStack after poking around a bit revolved around status responses. If, within a service, you have not overridden a method for a specific http verb then you do not get a nice instant 405 Method Not Allowed response. You instead get a 500 Internal Server Error with the available mime-type representation of the error object and stack trace. In an attempt to rectify this, I ended up creating an interim ErrorHandlingRestServiceBase<TResource> abstract class as follows:
public abstract class ErrorHandlingRestServiceBase<T> : RestServiceBase<T>
{
     protected override object HandleException(T request, Exception ex) {
         if (ex is NotImplementedException)
             return new HttpResult(ex)
                    { StatusCode = HttpStatusCode.MethodNotAllowed };

         return base.HandleException(request, ex);
     }
 }

The service then derives from this. Not the most elegant solution, but the only way I could see you it could be done. Having to implement functionality through inheritance rather than loosely coupled hooks can lead to complexity over time.

CustomSerialization

Another thing I didn’t get a chance to look at in more detail was customising your final mime-type related representation of your resource on the way back to the client. OpenRasta handles this excellently through the concept of a Codec, which is hooked up as a representation of a Resource with the ResourceSpace.Has syntax. This helps to leave the implementation of the request decoupled from the representation of the resource.

ServiceStack doesn’t seem to have an equivalent of this concept. In an attempt to ease you into an out-of-the-box implementation, it takes care of this all for you.

Summary

In my opinion, ServiceStack does deliver on its promises, it’s intuitive, user friendly and quick to set up. I’m sure if I’d had as much time with it as I have had with OpenRasta, I’d have found out ways around the issues outlined above.

Currently I don’t see anything that would prompt me to think about using it instead, but as a simple framework to quickly get an application up and running it’s definitely a winner.

The project is available here

Links

REST in Practice and OpenRasta

Posted in OpenRasta, REST on February 2nd, 2011 by gregsochanik – 5 Comments

After having read the o’Reilly book “REST in Practice” , I set myself the challenge of using OpenRasta to create a basic RESTful web service.

I decided for the first day to just concentrate on getting a basic CRUD app as outlined in chapter 4 working. This involved the ability to create, read, update and delete physical file xml representations of Artists. It is described in the book as a Level 2 application on Richardson’s maturity model, as it doesn’t make use of Hypermedia yet.

One reason why OpenRasta is such a good framework to implement a RESTful service is that it deals with “resources” and their representations. As outlined in “REST in Practice”, a resource is defined as any resource accessible via a URI, and OpenRasta deals with this perfectly as it was built to handle this model from the ground up.

The Basic Web Service

For the basic web service I created an ArtistHandler in the normal OpenRasta way, creating c# methods within the Handler for each of these four HTTP verbs:

  • GET for reading.
  • POST for creating.
  • PUT for updating.
  • DELETE for deleting.

I used the [HttpOperation] attributes just to make the relationship between the method and the verb more explicit, OpenRasta will actually auto map a method with the name Post() to the POST verb and so on.

The main aim of this exercise was to discover exactly what http response statuses and headers I should be returning, and whether it was possible to adhere strictly to the guidelines using OpenRasta.

The HTTP template I used for the endpoint was:

/artist/{artistId}

Http Responses

The Responses I wanted to give were structured as they are outlined in the book, and by 3w.org e.g:

GET /artist/{artistId}
  • Returns a 400 BadRequest along with a list of errors, if artistId not supplied.
  • Returns a 404 NotFound if record for that artist is not found
  • Returns a 200 OK along with the record if the record was found
  • Returns a 500 Internal Server Error on exception
POST /artist
  • Returns a 400 BadRequest along with a list of errors, if any parameters not supplied.
  • Returns a 302 Found along with the Location uri of the resource if it already exists.
  • Returns a 201 Created along with the Location uri of the new resource on success (this could also contain the body of the new resource)
  • Returns a 500 Internal Server Error on exception
PUT /artist/{artistId}
  • Returns a 400 BadRequest along with a list of errors, if any parameters not supplied.
  • Returns a 404 NotFound if record for that artist is not found
  • Returns a 204 NoContent along with the Location uri of the updated resource on success(not sure about this myself, but was specified in the book)
  • Returns a 500 Internal Server Error on exception
DELETE /artist/{artistId}
  • Returns a 400 BadRequest along with a list of errors, if any parameters not supplied.
  • Returns a 404 NotFound if record for that artist is not found
  • Returns a 204 NoContent on success.
  • Returns a 405 MethodNotAllowed on any IO exception
  • Returns a 503 Service Unavailable on any other exception

Issues

I had a couple of small issues with responses and OpenRasta. For instance, there is not a set OperationResult representing a 503 Service Unavailable response, but I could create my own by changing some settings in an InternalServerError Response, or by inheriting from the OperationResult class so no problems there.

Also, I wasn’t able to pass POX (Plain Old Xml) to the POST endpoint without OpenRasta throwing an internal exception, something which I’ll have a look at in due course.

Using Curl

I used Curl to test the endpoints, I tried Fiddler, but OpenRasta would always return a 415 Media Not Supported response. I imagine this was due to one of the headers not being specified properly, again this may be worth looking into but due to time constraints I didn’t bother. Using Curl is quick and easy, I just used variations on the following:

$ curl -v "http://localhost/restful_service/artist" -X "POST" -d "Id=100022&Name=WASP&Genre=LameRock"

Reaching Level 3

One thing you need to do to make a service move towards a Level 3 rating, is to offer up links to be able to access endpoints related to this resource, e.g. links to page to the previous or next record, or a link to fulfil or pay for an order. As a nod to this, I created a link to DELETE a record that is returned when you GET an artist e.g.

<link rel="artist" href="http://localhost/restful_service/artist/10010" method="DELETE"/>
“REST in practice” recommends the use of Atom feeds to truly create a Level 3 restful service, but Martin Fowlers post on the Richardson maturity Model suggests simply using standard html style link tags like I have used for the DELETE link above.

Wish List

There were many other things I would have liked to look at, namely Caching, E-Tags, creating Atom feeds and implementing OAuth, but I ran out of time.  At the time of writing, OpenRasta does not support OAuth out of the box, but according to this post it is something they are looking into.

An interesting move forward would be to create an

OAuthAuthenticationScheme : IAuthenticationScheme
within our own fork of OpenRasta. (https://github.com/7digital/openrasta-stable)

You can grab the project from here:

(https://github.com/gregsochanik/RESTfulService)

Links

Richardsons Maturity Model

Case insensitive query parameters with OpenRasta

Posted in OpenRasta on September 8th, 2010 by ghay – 2 Comments

Our API currently accepts case insensitive query parameters e.g. pagesize == pageSize == PaGeSiZe. Unfortunately OpenRasta is a lot more strict. If we have a URI mapped:

ResourceSpace.Has.ResourcesOfType<ApiResponse>()
	.AtUri("artist/search?q={searchterm}&pagesize={pagesize}")

and we make a request for “artist/search?q=bob+marley&pageSize=10″, the page size query parameter is not processed correctly. To deal with this we wrote a Pipeline Contributor to lowercase the query parameters before the URI is matched.

public class QueryParamLowerCaser : IPipelineContributor {
	public void Initialize(IPipeline pipelineRunner) {
		pipelineRunner.Notify(LowerCaseQueryParams)
			.Before<KnownStages.IUriMatching>();
	}
 
	public PipelineContinuation LowerCaseQueryParams(ICommunicationContext context) {
		var uri = context.Request.Uri;
		var newQuery = LowerCaseQueryString(uri.Query);
 
		context.Request.Uri = new Uri(uri.GetLeftPart(UriPartial.Path) + newQuery);
 
		return PipelineContinuation.Continue;
	}
 
	private static string LowerCaseQueryString(string queryString) {
		var queryParams = HttpUtility.ParseQueryString(queryString);
		var lowerCasedParams = new List<string>();
 
		foreach (string queryParam in queryParams) {
			lowerCasedParams.Add(queryParam.ToLower() + '=' + queryParams[queryParam]);
		}
 
		var newQuery = "?" + string.Join("&", lowerCasedParams);
		return newQuery;
	}
}

This can be wired into the pipeline in your Configuration Source:

ResourceSpace.Uses.PipelineContributor<QueryParamLowerCaser>();

At the moment this affects every request, but it could easily be modified to be more selective.

UPDATE: Following a suggestion from Seb this has been converted into a (more lightweight) UriDecorator

	public class QueryParamLowerCaser : IUriDecorator
	{
		public bool Parse(Uri uri, out Uri processedUri)
		{
			processedUri = LowerCaseQueryString(uri);
			return true;
		}
 
		private static Uri LowerCaseQueryString(Uri uri)
		{
			var queryParams = HttpUtility.ParseQueryString(uri.Query);
 
			var lowerCasedParams = new List<string>();
			foreach (string queryParam in queryParams)
			{
				if (queryParam != null)
					lowerCasedParams.Add(queryParam.ToLower() + '=' + queryParams[queryParam]);
			}
 
			var newQuery = "?" + string.Join("&", lowerCasedParams);
 
			return new Uri(uri.GetLeftPart(UriPartial.Path) + newQuery);
		}
 
		public void Apply() { }
	}

Then you just need to register it with your DependencyResolver.