Friday, 1 August 2008

How to write a simple Windows Communication Foundation - WCF service and client

In an earlier post, I provided an overview of Windows Communication Foundation (WCF) and likened it to wargaming. Well I have finally got around to write a series of posts detailing how to write and configure WCF services. Better late than never!

I needn't worry about how and where my service will be hosted, how clients will connect to it or indeed what protocol will be used. It doesn't matter, because at the moment I only want to think of my service in terms of its interface and implementation. i.e. What does it look like and what does it do?

I plan to write a flight information service that will be used by internal clients here at QA Airways. It is likely that our employees based at remote airports will need to access the service and so Http is likely as a protocol. In time we could share (and charge for) this service with business partners such as travel agencies.

Some form of authentication will no doubt be called for. However, as I have already said, I do not want to get bogged down in protocols and hosts. With WCF it needn't impact on how I write my service.

So I have decided to paint an army, ahem, write a WCF service.

Let's get started

Alright then, I'll simply dive in.

In Visual Studio 2008, there are several templates for WCF. For now, I will simply choose WCF Service library.

The resulting project contains a number of files that hold the key ingredients for my WCF service.

The file IService1.cs contains my interface (or Service Contract) called IService1. I shall be making some changes here so that the service contract defines methods that I require for my service.


The file Service1.cs contains the implementation of my service contract called Service1. Once my service contract has been updated, I shall make changes here to properly implement my service.


The file IService1.cs contains a class CompositeType which is a Data Contract. I have no need for a custom/complex type yet as I shall be using primitive types to pass data back and forth. So I will remove the entire CompositeType class.


The App.config file is perhaps the most important part of the project. This is where I will control what interface(s) will be used, where the service will be deployed and what protocol(s) it will use. However, it is too early for that.


The story so far

I have created a WCF Service project.

It comprises the following files:
  • IService1.cs
  • Service1.cs
  • App.config

IService1.cs contains an interface (Service Contract) IService1 and a class (Data Contract) CompositeType.

I deleted CompositeType.

Service1.cs contains a class Service1 that implements IService1.

Define the contract

Obviously, I don't want an interface called IService1 nor a service called Service1. So I use Edit / Find and Replace / Replace in files to rename every instance of IService1 to IFlightService and Service1 to FlightService.

In case you are wondering why I don't use Refactor to do the renaming, it is because Refactor does not 'do' config files and my interface and service class are referred to in App.config. I don't want to miss any!

I remove the GetDataUsingDataContract method from both IFlightService and FlightService.
Finally I replace the GetData method in both the interface and class with GetFlights as follows:


As you can see, the GetFlights method simply returns a string of contrived flight numbers. In fact we would probably query a data source at this point.

OK, the service is good to go. All we need to do now is test it before sitting down to write a client application.

Test the service

You'll like this bit!
In Visual Studio 2005, you would have to write a client application in order to test your service which was time consuming and delayed the 'inevitable' runs first time moment. However, in Visual Studio 2008 you are able to use the built in test client. WcfTestClient.exe is launched automatically whenever you run a WCF service.

This is thanks to a /client command line argument:

So in order to test my service I simply press F5.

The test client loads up and shows me that there is only one method and allows me to interactively invoke it with sample/test data.

It works!


One other point.

When you create web services, you rely on IIS to host your service for you. With WCF you are free to implement your own host. For example you could write a console application host, a Windows application host or possibly even a Windows service host. In fact you could even have IIS do it for you just like with web services.

None of this is necessary for now though because by default, WCF services are hosted by the built in WCF host WcfSvcHost when launched from within Visual Studio 2008.

What about the bindings ?

As I mentioned earlier, once I have written the service I want to leave decisions such as the transport to use up to the administrator. So the more that can be achieved with the App.config file, the better.

Let's look at some key elements.

Firstly there is the service name:

This is the name of the service class. It is declared within a services element.

Note that you can define more than one service in this section.

Each service may have more than one end point. For example, one for tcp clients and another for clients using http. These endpoints might share the same base address. So by default, a baseAddress section is added to the config file for each service class.


By default each service is given two end points. One that uses wsHTTP binding for all clients and another that uses Mex binding. The Mex binding endpoint is used by Visual Studio 2008 when adding a reference to a WCF service. The Mex endpoint permits discovery.

One last point of interest regarding config files is/are behaviours. These are named combinations of options/settings that you can assign to one or more services.

The behavior FlightServiceBahavior below is used by the FlightService service.


Write a client application

And finally ..

Time to write the client.

I add a new Windows Forms Application project called WinClient to the solutions and create a simple UI:


I now need to add code to my client that acts as a proxy to my service. To do that, I select Add Service Reference from the Solution Explorer. When I click Discover, my service is located thanks to the Mex binding endpoint defined in the config file.

All I do now is simply give my proxy class a better namespace e.g. Flights and click OK.

The first thing to do in my Search button is instantiate the proxy class.


This class FlightServiceClient represents the proxy for the FlightService class in the WCF service. This proxy will contain all the methods (just GetFlights for now) that exist in the actual service. However, they do not contain the same code. Rather, they contain the code necessary to call the methods remotely.
I now write the code to call my service and receive the result.


Finally, I set the StartUp Project to my WinClient project and hit F5 one last time.

I type in two airports, click Search and wait for the FlightService to return me a list of flight numbers.

Turn off discovery

Now that I have written my client application, I no longer need a Mex endpoint enabled. In fact it desirable to remove the Mex endpoint once your client is written so that your service cannot be 'discovered' by unscrupulous developers.

I remove the mex endpoint and change the httpGetEnabled property in my FlightServiceBehavior to False.

In conclusion

So there you have a very simple WCF service and client.

I have written a WCF service and in the process looked at Service Contracts, EndPoints in config files. Mex binding to allow discovery and the creation of a service proxy class.

In a future posting I will show how easy it is to change the bindings for a WCF service.

Training ?
Should you require training in WCF we currently offer the following course: 

Building Effective Windows Communication Foundation applications using Visual Studio 2010


See you soon

Phil Stirpé
"I don't do average!"

No comments:

Post a Comment