WCF Web API–Self-hosting

This is the second post on a series about the new Preview 4 of WCF Web API. In the previous post, I introduced the elementary aspects of the programming model, namely: resource classes, operations, HttpRequestMessage and HttpResponseMessage. The main outcome of the post was the TodoResource class.

In this post, I describe how to self-host this class. Lets the code do the talking.

class TheHostProgram
{
    static void Main(string[] args)
    {
        var instance = new TodoResource(new ToDoMemoryRepository());
        using (var host = new HttpServiceHost(instance, "http://localhost:8080/todo"))
        {
            host.Open();
            ShowEndpointsOf(host);
            WaitForKey();
        }
    }

    private static void ShowEndpointsOf(ServiceHost host)
    {
        Console.WriteLine("Host is opened with the following endpoints:");
        foreach (var ep in host.Description.Endpoints)
        {
            Console.WriteLine("\tEndpoint: address = {0}; binding = {1}", ep.Address, ep.Binding);
        }
    }

    private static void WaitForKey()
    {
        Console.WriteLine("Press any key to stop host...");
        Console.ReadKey();
    }
}

That’s it.

Notice:

  • The ShowEndpoints and WaitForKey methods are just utility functions to show the opened endpoints and wait for user input.
  • The use of a new service host type – HttpServiceHost.
  • For simplicity, the service uses InstanceContextMode.Single. This means that I can pass the resource class instance directly to the service host. This allows me to resolve its dependencies (the IToDoRepository) manually. In a future post, I will show how to use an IoC/DI container to obtain the resource class instances.
  • No endpoint has to be explicitly added. The HttpServiceHost automatically adds an endpoint for each defined base address defined in the constructor.
  • This default endpoint will have the “http://localhost:8080/todo” base address. Note that the URI templates defined in the resource class are relative to this base address. For instance, a GET request to “http://localhost:8080/todo/123” will be associated with the GetToDo operation (“{id}” template). The template’s id variable will be bound to “123”.

Explicit endpoints can also be added using the old AddServiceEndpoint method, before the service is opened:

host.AddServiceEndpoint(typeof(TodoResource), new HttpBinding(), "http://localhost:8080/todo2");

The host will not add default endpoints if there are explicit endpoints added.

When explicitly adding an endpoint, notice  the usage of a new binding – HttpBinding. This is the binding also used in the default endpoints.

Currently, it is even possible to use the old ServiceHost to host a resource class. However, the new HttpBehavior behavior must be added to each endpoint.

var repository = new ToDoMemoryRepository();
repository.Add(new ToDo("Must learn HTTP better"));
var instance = new TodoResource(repository);
using (var host = new ServiceHost(instance))
{
    var ep = host.AddServiceEndpoint(typeof(TodoResource), new HttpBinding(), "http://localhost:8080/todo2");
    ep.Behaviors.Add(new HttpBehavior());
    host.Open();
    ShowEndpointsOf(host);
    WaitForKey();
}

It is this HttpBehavior and the HttpBinding that “insert” the new WCF Web API model into the WCF runtime. When using HttpServiceHost, this behavior is automatically added.

3 thoughts on “WCF Web API–Self-hosting

  1. Pingback: HTTP content classes « Pedro Félix’s shared memory

  2. Mike

    Pedro, did you use a Project type of Console Application to host your ToDoResource? I’ve developed an wcf web application using the ASP.NET Web application type and have tried to host it from a WCF Service app and Console app but I can’t resolve dependencies for the HTTPService host etc. I also tried just adding a Resource class to a WCF Service app but the Nuget wcf web api package fails to install. Obviously, new ground for me; I appreciate any advice. Thanks.

    Reply
  3. J

    It seems to me that you’d either use HttpServiceHost OR HttpListener, but not both. What is the difference between them? Is there any documentation on these WebAPI classes?

    When I dove in to WebAPI, I landed in HttpListener, but I’m having trouble in that my responses are not getting their headers written – we’re just jumping straight to the body.

    Reply

Leave a comment