Developing a WCF Service

It is typical to have projects based on a client-server architecture where the server publishes a number of services. These services are normally Web-Services, and as so are available through the SOAP protocol.

The "traditional" way of implementing these services is by using ASMX, but nowadays you have another great alternative – Windows Communication Foundation (WCF) in .NET 3.5.

This, being my first WCF post, intends to demonstrate that developing a simple WCF service is as easy as doing it in ASMX, while allowing us to make future evolutions on our service architecture to support everything that WCF makes available.

 

Well, as always you start out by creating a new Visual Studio project. I chose to use the existent project template ‘WCF Service Library’ (but some of you may want to start by an empty project 😀 ).

This creates a project with the following list of files (I changed the service name to ‘Service’, and I only list the WCF most important files:

  • IService.cs – Describes the exposed service interface. This is where we will namely define the [ServiceContract] (The service itself) and the [OperationContract]‘s (The operations exposed by the service). More information in Designing and Implementing Services.
  • Service.cs – The service interface implementation class. This is where the actual code of the service operations will be contained. More information in Implementing Service Contracts.

There is another important file, App.Config, that contains the service configuration (e.g. service listening url), but I will refer to this file later when talking about the service hosting (creates the service and controls its context and lifetime). More information in Hosting Services.

So a simple service contract could be:

[ServiceContract]
public interface IService
{
    [OperationContract]
    Int32 GetTotalNumberOfCustomers();
 
    [OperationContract]
    Customer GetCustomer(Int32 customerId);
 
    [OperationContract]
    List<Customer> GetCustomers();        
}

This code defines a service contract (IService) that exposes three operations (operation functionality is self explanatory):

  • GetTotalNumberOfCustomers
  • GetCustomer
  • GetCustomers

You will notice that in the code we are referring a custom class that is not contained anywhere in the service contract, that is the Customer class. This class must be described in WCF like a [DataContract] because it is a new, complex data type that WCF does not know how to serialize. More information in Using Data Contracts.

Our data contract is defined like this:

[DataContract]

public class Customer

{

    [DataMember]

    public Int32 Id { get; set; }

 

    [DataMember]

    public String Name { get; set; }

 

    public Customer()

    {

        Id = 0;

        Name = String.Empty;

    }

}

One important aspect of data contracts are the [DataMember] properties, that are properties to be exposed by the data contract.

 

At this point we are ready to implement our service contract, that for this example is very simple, and obviously not production code:

public class Service : IService

{

    private List<Customer> Customers = new List<Customer>()

    {

        new Customer() {Id = 1, Name = "Customer1" },

        new Customer() {Id = 2, Name = "Customer2" },

        new Customer() {Id = 3, Name = "Customer3" }

    };

 

    public int GetTotalNumberOfCustomers()

    {

        return Customers.Count;

    }

 

    public Customer GetCustomer(int customerId)

    {

        return Customers.First(customer => 

        {

            return customer.Id == customerId;

        });

    }

 

    public List<Customer> GetCustomers()

    {

        return Customers;

    }

}

 

Our service is now ready to be hosted and this is one of the beauties of WCF in the sense that the hosting environment can be a:

  • Windows/WPF Application
  • Console application
  • Windows Service
  • IIS/WAS

Each of them has advantages and disadvantages an again I refer you to Hosting Services (look at the Choosing a Hosting Environment table). Take into attention that the Service Library that you develop is always the same regardless of the hosting environment that you choose, and even if you choose one hosting environment now, you can choose another later and easily change between them.

For developing/debugging purposes I normally choose for hosting a simple WPF application with just two buttons (Start and Stop), where I place the following code (the Logger object is of log4net ILog type):

private void StartServiceHost()

{

    Logger.Info("StartServiceHost: Starting service hosting...");

 

    // Create service host

    _serviceHost = new ServiceHost(typeof(SampleService.Service));

    

    try

    { // Open service host

        _serviceHost.Open();

 

        Logger.Info("StartServiceHost: Service hosting success.");

    }

    catch (Exception ex)

    {

        Logger.Fatal("StartServiceHost: Could not start service hosting.", ex);

    }            

}

 
private void StopServiceHost()

{

    // Close service host

    _serviceHost.Close();

}

Now, you just have to properly configure the application configuration file (remember we talked about it earlier), and you are ready to test your service. Note that I configured the service hosting all thru the App.Config file and as simple and compatible as possible with a ASMX (e.g. Basic HTTP binding).

Note: I will differ binding’s and other configuration explanations to another time. Right now I just want you to see how you can get started with WCF.

<configuration>

    <system.serviceModel>

        <services>

        <service behaviorConfiguration="SampleService.Service.Behavior" name="SampleService.Service">

            <host>

                <baseAddresses>

                    <add baseAddress="http://localhost:8080/SampleService"/>

                </baseAddresses>

            </host>

            <endpoint    address="/Service.svc"

                        binding="basicHttpBinding"

                        name="IService_BasicHttpEndpoint"

                        contract="SampleService.IService"

                        bindingConfiguration="IService_BasicHttpBindingConfiguration">

            </endpoint>

        </service>

    </services>

 

    <behaviors>

        <serviceBehaviors>

            <behavior name="SampleService.Service.Behavior">

                <!-- To avoid disclosing metadata information, 

      set the value below to false and remove the metadata endpoint above before deployment -->

                <serviceMetadata httpGetEnabled="True"/>

                <!-- To receive exception details in faults for debugging purposes, 

      set the value below to true.  Set to false before deployment 

      to avoid disclosing exception information -->

                <serviceDebug includeExceptionDetailInFaults="True" />                

            </behavior>

        </serviceBehaviors>

    </behaviors>

 

    <bindings>

        <basicHttpBinding>

            <!-- Service host binding configuration -->

            <binding name="IService_BasicHttpBindingConfiguration"

                             maxBufferSize="65536" maxBufferPoolSize="52428"

                             maxReceivedMessageSize="65536" transferMode="Buffered">            

                <readerQuotas maxDepth="32" maxArrayLength="16384"

                                            maxBytesPerRead="4096" maxNameTableCharCount="16384"

                                            maxStringContentLength="8192"/>

            </binding>

        </basicHttpBinding>

    </bindings>

    

</system.serviceModel>

 

<configuration>

If you now run the WPF application and point your browser to http://localhost:8080/SampleService you should see a welcome page telling you that you have created a service.

You are now ready to start writing a client application that will call your service operation contracts (my next post will be about this part, but you have everything you need in the service welcome page).

To end, I just want to show you how easy it is to change the hosting environment to IIS for example. For hosting in IIS you just have to follow these steps:

  • Create a new web application in IIS
  • Place the presented App.Config <system.serviceModel> tag in a Web.Config file
  • Deploy the service library assembly to the web application bin directory
  • Create a special file, in my example called Service.svc, with the following content:
<%@ServiceHost language="C#" Debug="true"

                             Service="SampleService.Service"%>

<%@Assembly Name="SampleService" %>

The only different part in hosting in IIS is just the need to create the .svc file that tells IIS which service should be instantiated.

Again, if you point your browser to http://localhost:8080/SampleService/Service.svc you should see the same page as before.

I hope that this can get you started in WCF more easily and I will try to show what other capabilities WCF provides in some next posts.

Leave a Reply

Your email address will not be published. Required fields are marked *