An Introduction to Windows Communication Foundation – Creating a basic service

This series of posts will talk about Windows Communication Foundation, starting with an introduction into the technology and how to use it in you project, moving onto more advanced topics such as using an IOC container to satisfy dependencies in your services.
Posts in this series:

Before the introduction of Windows Communication Foundation (WCF) in 2006 there were lots of different Microsoft technologies for building distributed systems. ASP.NET Web Services (ASMX), Web Service Enhancements (WSE) extensions, Microsoft Message Queue (MSMQ), the Enterprise Services/COM+ runtime environment and .NET Remoting to name the key ones. Microsoft were keen to point out that there was nothing wrong with these technologies, simply that there are too many of them. Building a distributed system required you to pick one of them as a fundemental technology which would send you down a specific technology strategy.

WCF is a single programming model that unifies all of the above approaches and more, and allows for a single technology choice to be used to support many different distributed systems scenarios.

Microsoft  describes WCF as

“a framework for building service-oriented applications. Using WCF, you can send data as asynchronous messages from one service endpoint to another. A service endpoint can be part of a continuously available service hosted by IIS, or it can be a service hosted in an application. An endpoint can be a client of a service that requests data from a service endpoint. The messages can be as simple as a single character or word sent as XML, or as complex as a stream of binary data.”

Don’t be put off by the reference to the often over hyped service orientation. WCF services can be used in many situations. It is often thought of as being too”enterprisy” for small applications. This is not the case at all. Services can be hosted in applications (Console, Winforms, WPF) as well as IIS and even a Windows Service. This opens up lots of possibilities for developing distributed applications. Many message formats are supported, including SOAP, plain XML and JSON. New formats are added as they gain traction within the industry.

If you have been reading about WCF you may have seen the ABC mnemonic when talking about endpoints;

  • A – Address: Where is the service?
  • B – Binding: How do I talk to the service?
  • C – Contract: What can the service do for me?
In WCF all communication occurs through an Endpoint. The ABC of WCF translates to some concrete steps that are followed when creating a WCF service:
  • You define a contract and implement it on a service – The language may be new but the concepts will be familiar. A WCF contract is an interface that defines service operations. The service implementation is simply an implementation of that interface.
  • You define a service binding that selects a transport along with quality of service, security and other options – This is usually done in configuration, but can be done in code if required.
  • You deploy an endpoint for the contract by binding it to a network address.  Configuration again. Tell WCF which contract interface should be associated with a particular endpoint.

Don’t worry if some of the terminology or concepts are new to you, we will cover these in more detail in the next section.

Creating you first WCF Service

Lets go ahead and create a new WCF Service Application project in Visual Studio, either in a new solution or an existing one, it doesn’t really matter for the purposes of this example. Be sure to target .Net3.5. There is a reason for this as .Net4.0 has lots of features to simplify configuration, but it is not that helpful to have lots of things defaulted behind the scenes when we are trying to understand how things work.

Visual Studio helpfully(?!) creates a service for us named Service1. A quick rename and we are done, right? Not quite. Although this service would work correctly, the way it has been created would not really be of any practical use in any but for the smallest of applications. The service implementation is in a code-behind on the .svc file and the interface is in the same file as the data contracts (the service model).

Lets just delete the files we don’t want and start again. Start with the code-behind file Service1.svs.cs and IService1.cs. Lets leave the Web.config for now as we can reuse the configuration already in there. If you were writing a full size application you may well want to structure your solution into several different projects for the different parts of the application. For this introduction I am going to use folders.

The first thing I am going to do is create a service contract. Remember that a service contract is just an Interface. Create a folder called Contract and an Interface within it, IProductService seems like a sensible name. Add a ServiceContract attribute to the interface. You will need a using statement for System.ServiceModel. Now we can add a service operation; called GetProductById(int productId). Each operation needs to have an OperationContract attribute. If this attribute is missing the operation will not be visible to WCF. The IProductService interface looks like this:

using System.ServiceModel;
using WcfServiceApplication.Domain;

namespace WcfServiceApplication.Contract
{
    [ServiceContract]
    public interface IProductService {

        [OperationContract]
        Product GetProductById(int productId);
    }
}

You will notice that the service operation returns a Product. I have defined this in the Domain folder. If an object is to be sent over the wire by WCF it needs to be attributed at the class level with DataContract and at the method level with DataMember (you will need to add a using statement for System.Runtime.Serialization) to indicate that the object can be serialised. I do not really want to get into the debate about returning Domain objects versus returning Data Transfer Objects from services at this stage as it doesn’t add much to the topic at hand. I will just say that for the purposes of this walk through I will use Domain objects, but for a non trivial application I would use DTO’s. The Product class looks like this:

using System.Runtime.Serialization;

namespace WcfServiceApplication.Domain
{
    [DataContract]
    public class Product
    {
        [DataMember]
        public int Id { getset; }

        [DataMember]
        public string Name { getset; }

        [DataMember]
        public string Description { getset; }
    }
}

Now we can implement the interface so the service can do something. I have given it a trivial implementation. In a real application the service would be responsible for doing something interesting such as performing some calculations or getting some data from somewhere.

using WcfServiceApplication.Contract;
using WcfServiceApplication.Domain;

namespace WcfServiceApplication.Implementation
{
    public class ProductService : IProductService
    {
        public Product GetProductById(int productId) {
            return new Product {
                                       Id = productId, 
                                       Name = "Product" + productId, 
                                       Description = "A nice product"
                               };
        }
    }
}

The next step is to tell the .svc file to use the new implementation we have created. Rename the file to productService.svc and edit the contents to point to the implementation.

<%@ ServiceHost Language="C#" Debug="true" 
    Service="WcfServiceApplication.Implementation.ProductService" %>

We only have the Web.config to go before we have a working service. Open Web.config and find the system.serviceModel section which contains the configuration for the WCF services.

In the system.serviceModel there are two further sections: services and behaviors.

Services – All services have their own section under services. There is just one right now which is incorrectly configured and we will fix things up as we go. The service has two attributes and one or more endoint elements:

  • name attribute – this should match the service attribute from the ProductService.svc, which is WcfServiceApplication.Implementation.ProductService.
  •  behaviorConfiguration attribute – this should match a service behaviour. We havent encountered one yet (its coming up in the behaviors section) so lets just change the value to WcfServiceApplication.ProductServiceBehavior in anticipation.
  • endpoints – As mentioned earlier, an endpoint is how a WCF service communicates with the outside world. A service can have one or more endpoints. Our example has two. Lets have a closer look at the first one.
    • address = “” – this is a relative address, which means that the address of this service will be relative to the base address. This is the most common address but can be different. It is also possible to add a base address if you want things to work differently. A good introduction can be found here.
    • binding=”wsHttpBinding” – a binding is used to define how to communicate with an endpoint. It has a protocol stack that determines things like security and reliability from messages sent to the endpoint. It describles the transport protocol to use when sending to the endpoint (HTTP, TCP etc). It also describes the encoding of the messages that are sent to the endpoint (text/xml etc). WCF has some binding to choose from that cover a variety of scenarios. We are using wsHttpBinding which offers good support for interoperation with other services that support the WS-* standards. Other bindings can be used depending on whether you need backwards compatibility with old asmx style services, or whether you want high performance when building WCF services that are also to be consumed by a WCF client for example. More information about bindings can be found here.
    • Contract – this should be changed to the location of the contract we created early, which is WcfServiceApplication.Contract.IProductService.

You may have noticed that this is the ABC of WCF I mentioned earlier. There is another endpoint with address=”mex”. This is to allow clients to be able to get the metadata for the service via SOAP calls. We can leave it in as we plan on using the metadata at a later stage. The services section now looks like this:

<services>
    <service name="WcfServiceApplication.Implementation.ProductService" behaviorConfiguration="WcfServiceApplication.ProductServiceBehavior">
      <endpoint address="" binding="wsHttpBinding" contract="WcfServiceApplication.Contract.IProductService">
        <identity>
          <dns value="localhost"/>
        </identity>
      </endpoint>
      <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
    </service>
  </services>

Behaviors – This section can have a number of behaviours which can be applied to a service. Remember that we changed the behaviorConfiguration value and we need to change the name of the behavior to be the same to enable our service to find it. The behavior has two elements:

  • serviceMetadata httpGetEnabled=”true” – this enables metadata exchange and also allows the WSDL to be access by a special URL (which is the service url with ?wsdl at the end). You don’t always need metadata exchange, but we will be using it later.
  • serviceDebug includeExceptionDetailInFaults=”false” – do we want to show useful debugging info? The default is false and will keep it that way. This may be useful if you are debugging a service but should not be used in a production environement.

The behavior section now looks like this:

 <behaviors>
      <serviceBehaviors>
        <behavior name="WcfServiceApplication.ProductServiceBehavior">
          <serviceMetadata httpGetEnabled="true"/>
          <serviceDebug includeExceptionDetailInFaults="false"/>
        </behavior>
      </serviceBehaviors>
    </behaviors>

Thats it. We are ready to run the service for the first time. The easiest way is using the WCF Test Client. highlight ProductService.svc in SolutionExplorer and hit F5. All being well WCF Test Client should load with the service visble. If you get any errors when you load the service it is very likely that there is a typo somewhere in either the files or the web.config.

Under the service you should be able to see the service along with the single service operation GetProductById(). Select the method to bring up the request and response panels for the method. You should be able to add a product Id (any number will do) and hit invoke to see the outcome.

That’s all there is to it. Of course there are a lot more configuration possibilities for more advanced scenarios, and we will cover some in future posts. In the next post I will cover how to create a client application to consume the WCF service we just created.

Posts in this series:

Advertisements

4 Responses to An Introduction to Windows Communication Foundation – Creating a basic service

  1. Pingback: Windows Communication Foundation – Consuming a WCF service with ChannelFactory « James Heppinstall: On Development

  2. Pingback: Windows Communication Foundation – Resolving WCF service dependencies with Unity « James Heppinstall: On Development

  3. Pingback: Windows Communication Foundation – Resolving MVC client WCF ChannelFactory dependencies with Unity « James Heppinstall: On Development

  4. Pingback: RESTful Web Services with Windows Communication Foundation « James Heppinstall: On Development

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

%d bloggers like this: