Basic WCF Services

I’m going to post a 2 part series on the basics of WCF services. In this first post I’m going to go over how to host a WCF service and how to manually create a proxy to execute against that service.

I’ll say right off the bat, I’m not a huge fan of the “Add Service Reference” method of consuming WCF services that Visual Studio provides. First, I hesitate at any auto generated code. I like full control of what’s going on and don’t want to worry about making changes to contracts and not knowing exactly how it will affect the ecosystem in which it lives. Along those lines the second reason I don’t like the “Add Service Reference” method is that it hides the implementation of what’s happening behind the scenes. You can always look at auto-gen’d code but it’s a pain to read through, not formatted very well, and who really takes the time to dig into it? Writing the code yourself will give you a better understanding of the functionality it takes to implement a web service. If you understand how to manually consume a web service and then want to use the “Add Service Reference,” then fine, that’s not the end of the world I guess.

The Service and Contract

The first thing we need when implementing a web service is just that, a service, some functionality. Below is a simple class that will perform two basic actions. Notice we’re implementing an interface, we’ll get to that below.

public class MyService : IMyService
{
    public void DoSomeWork(bool parameter)
    {
    }

    public int ReturnAnInt()
    {
        return 0;
    }
}

Now that we have a service that will perform some work, we need a contract to tell WCF which operations to expose as web services. I included a using statement where the attributes are found. You’ll have to add a reference to the System.ServiceModel.dll assembly as well.

using System.ServiceModel;

[ServiceContract]
public interface IMyService
{
    [OperationContract]
    public void DoSomeWork(bool parameter);

    [OperationContract]
    public int ReturnAnInt();
}

The ServiceContract attributes will tell WCF that this class has operations that will be exposed as web services. The OperationContract attribute specifies which specific methods will be exposed. I haven’t created services with operations that aren’t exposed as operations, though it’s possible to do. I tend to stick with the Single Responsibility Principle here and say that in general all operations on a service should be exposed otherwise it probably doesn’t belong.

I should note that you can specify the ServiceContract and OperationContract attributes directly on the service and totally forget about the interface but try to remember that abstraction and decoupling will greatly increase the flexibility of your application and if used with a unit testing framework can greatly increase the quality.

Hosting

So now we have a service and we need to expose it to the world. This is done using a class called ServiceHost.

public class HostMyService
{
    private readonly ServiceHost serviceHost;
    private readonly IMyService myService;

    public HostMyService()
    {
        myService = new MyService();
        serviceHost = 
            new ServiceHost(
                myService,
                new Uri("http://localhost:8080", UriKind.Absolute),
                new BasicHttpBinding());
    }

    public void StartService()
    {
        serviceHost.Open();
    }
}

In the above implementation, we first created an instance of the service. We then created the ServiceHost object and passed into the constructor the instance of the service, the URI endpoint that defines where this service is going to be exposed, localhost on port 8080 in this case and a binding object. The purpose of the binding is to define how the service will communicate. There are many types of bindings and each have numerous properties that can be set to customize the behavior of the service. For this example we’ll use the most simple one, BasicHttpBinding.

Assuming we call StartService on the HostMyService object, our WCF service is now exposed. This doesn’t do us much good if we can’t consume it in some way. So lets create a proxy to execute against our new web service.

Consuming the Service

We’ll first need the IMyService contract. When I design web services I tend to create a “Common” project that is included in all Visual Studio solutions that live in my ecosystem. In a client/server style environment, this means that I’ll have two solutions, one for client and one for server. I’ll create a Common project that is included in both and contains all of my service contracts. This is a nice place to include a constants file as well, if you so desire.

Assuming we have access to the contract, we’ll use a ChannelFactory class to create a connection to the web service and execute the operations we’re interested in. Implementation is below.

public class MyServiceProxy : IMyService
{
    private readonly IMyService proxy;
    private readonly ChannelFactory<IMyService> channelFactory;

    public MyServiceProxy
    {
        channelFactory =
            new ChannelFactory<IMyService>(
                new BasicHttpBinding(),
                new EndpointAddress("http://localhost:8080"));
        proxy = channelFactory.CreateChannel();
    }

    public void DoSomeWork(int parameter)
    {
        proxy.DoSomeWork(parameter);
    }

    public int ReturnAnInt()
    {
        return proxy.ReturnAnInt();
    }
}

And there it is, we now have a class we can instantiate to execute against our web service. Of course this is a synchronous call which is undesirable so in the next post in this series I’ll talk about creating async WCF services. Going async is not much more than a few modifications to the service and it’s contract. This is required if you’re doing any Silverlight work as the Silverlight runtime will enforce all WCF services to follow the async pattern.

Advertisements

One thought on “Basic WCF Services

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s