Building Declarative WCF Services in .NET 4.0

Building Declarative WCF Services in .NET 4.0

lmost any application requires some sort of workflow, where the application performs one or more actions through processes made up of multiple activities. Windows Workflow Foundation (WF) lets developers create these workflows using a rich set of activities that are very easy to use. Within the WF activities that make up a workflow, you may sometimes need to invoke an external WCF service, sending and receiving appropriate messages.

.NET 3.5 supported WF-to-WCF service interaction by supplying specific WF activities that could call an external WCF service from within a workflow. The drawback with this approach is that developers needed to use two different programming models to work with WCF and WF. For example, you had to define WCF artifacts and manage them separately?then integrate them with WF activities. However with .NET 4.0, you can define a WF workflow as a WCF service declaratively, with XAML (eXtensible Application Markup Language). This article introduces this new feature and showcases how you can leverage it to create declarative WCF services through workflows.

One key feature of .NET 4.0 is the seamless integration between WCF and WF. This integration greatly simplifies the developer experience around declarative workflows and services, and it’s all made possible by the XAML-only model, which is completely based on declarative attributes. You can describe the workflow-based WCF service solely in XAML, including service contract definitions, endpoint configurations, and even the actual service implementation.

These declarative XAML-based services provide a layer of abstraction. Essentially, you create a model of the service by defining what you want the service to do, rather than writing code to specify how to do it.

Defining Service Contracts Declaratively

In earlier versions of the .NET Framework, a simple WCF service contract definition looked similar to the one shown below:

public interface IHelloWorld{ string HelloWorld(string input);}

Using the declarative WCF services feature in .NET 4.0, you could define the same service contract as follows:


The element specifies the name of the contract and serves as a container for the operation contracts that make up the service contract. As the name suggests, the element specifies the operations exposed by the service. The parameters to an operation are represented by the elements, which are children of the element. There will be one element for each argument or return value that the operation accepts or returns. The element holds information about the argument, such as its data type and direction. The Direction attribute specifies whether an argument is an In, Out, or In/Out argument.

After defining the service contract in XAML, the next step is to define how to project the contract onto the wire so that service consumers can leverage appropriate protocols to consume the service. .NET Framework 4.0 introduces a new feature named Contract Projection that lets you clearly separate the logical contract definition from the actual representation of the messages that are sent and received:


By inheriting from the single logical service contract, you have an option to project different service contracts, such as SOAP- or REST-based contract projections, etc., based on the service consumers’ needs.

Implementing Service Logic Declaratively

With the contract definitions and projections in place, the next step is to actually implement the service logic in XAML. To do that, you need to encapsulate the details of the implementation in a <Service.Implementation> element. The following structure shows the element children required to define a service contract:


Table 1 shows the elements you need to declare WCF services in XAML.

Table 1. WCF Declarative Elements: The table lists and provides a brief explanation of the elements used to express a WCF service declaratively in XAML.

Acts as a root element that contains all the details of the service including the endpoint, service implementation, and so on.
Lets you specify the contract projections exposed through a service
Holds implementation logic for a declarative service
Specifies the name of the service implementation that contains the workflow implementation
Contains the body of the actual workflow implementation
Specifies the service end point; contains an element for each end point the service exposes
Specifies details of the service, including the name of the service interface
Specifies details of the operation, such as the name of the operation
Specifies the names and direction of arguments supplied to the operation.
Lets you define variables and associate them with a workflow that implements the operation

Listing 1 contains the complete service definition for a service interface named IHelloWorld, which exposes a method named HelloWorld().

Note that Listing 1 contains the actual service implementation inside the <WorkflowServiceImplementation.Body> element. That element contains the <ServiceOperation.Body> element, which uses the <DynamicActivityAction> element to specify the input and output variables to the workflow operation:


You assign the input variable as the output from the HelloWorld method through the <wma:Assign> element:


Then you define the service endpoint using the element, in which you specify the end point URI as well as the type of the binding (BasicHttpBinding in this case):


After you have the end point defined, you can specify the contract projections that will be made available for the IHelloWorld service through the <EndPoint.ContractProjection> element:


That?s all there is to exposing a WCF service through XAML declaration. Although at first the XAML looks a little intimidating, you'll find that it becomes very straightforward after you've created a few of these.

Hosting a Declarative Service

Now that you have created the service, the next step is to host the service through a hosting application. For example purposes, a simple console application suffices to host the service.

class Program{   static Service service;    static void Main()   {      Console.WriteLine("Loading WCF Service");      using (TextReader reader =          File.OpenText("HelloWorldService.xml"))      {         service = (Service)XamlServices.Load(reader);      }      Uri address = new          Uri("http://localhost:8000/HelloWorldService");      WorkflowServiceHost1 host = new          WorkflowServiceHost1(service, address);      try      {         Console.WriteLine("Opening Service");         host.Open();                         Console.ReadLine();      }      catch (Exception ex)      {         Console.WriteLine(            "Service terminated with exception {0}", ex.ToString());      }      finally      {         host.Close();      }   }}

The preceding code loads the XAML file by invoking the System.IO.File.OpenText() method, passing in the name of the XAML file that contains the service definition. Then it obtains a reference to the service by calling the System.Xaml.XamlServices.Load() method, passing in the reader returned by the OpenText method.

With the service loaded, the code opens an endpoint and listens to incoming requests through that endpoint:

Uri address = new Uri(    "http://localhost:8000/HelloWorldService");WorkflowServiceHost1 host = new    WorkflowServiceHost1(service,  address);try{   Console.WriteLine("Opening Service");   host.Open();                   Console.ReadLine();}               

At this point, a service consumer can invoke the service and get the response back.

You've seen a working example of how to use the new declarative WCF services feature introduced with .NET 4.0. As you can see, declarative WCF services provide you with an easy-to-use, configuration-based services model, which is both flexible and extensible. It also opens up a window of opportunities for innovative use of WCF services in your .NET solutions.


About Our Editorial Process

At DevX, we’re dedicated to tech entrepreneurship. Our team closely follows industry shifts, new products, AI breakthroughs, technology trends, and funding announcements. Articles undergo thorough editing to ensure accuracy and clarity, reflecting DevX’s style and supporting entrepreneurs in the tech sphere.

See our full editorial policy.

About Our Journalist