I am constantly surprised when speaking with people how few have heard of or use the “Service Interface” pattern. It is actually a very straightforward pattern, is very little work to use, but brings such practical, quantifiable, visible, benefits I think it has to be one of my all time favourites. The Web Service Software Factory embodies a particularly good implementation of the pattern, too, so be sure to check that out. In fact, I’d go so far as to say that the easiest way to get familiar with this pattern is to read this post (obviously J) and then try the factory.
There’s already a bunch of documentation out there, including the pattern description on MSDN (although the corresponding implementation advice is a little dated due to the advent of things like WCF). The Web Service Software Factory documentation also describes the pattern, adding some more information and a sample to the MSDN docs.
The basics
What on earth is this pattern then? Well basically it is there to keep the “surface area” of a web service independent from the Business Logic. In exactly the same way as you would partition your User Interface from your Business Logic, it is wise to partition your Service Interface.
Separating these concerns means that your logic can evolve in implementation without breaking consumers of your service (remember that contracts between services are quite brittle in many cases), and also to evolve the communication mechanisms and formats your service uses without affecting your logic. Makes a lot of sense, huh?!
The Service Interface is also the ideal place to do things like message logging, exception shielding, versioning, and so on. All of these concepts are highly recommended for consideration before you deploy the first version of your service.
Pattern Components
There are a number of components that work together to form a well structured Service Interface. These components are depicted below;

I’m sure you’ve noticed that I don’t like to draw and talk too much without dropping down to see what this really means in code. So taking each component, one at a time, let’s see what they are, what they do, and what the code looks like. I’ll use WCF in this example, but the sample concepts can apply to other technologies.
Data Contracts
Data Contracts are the reusable entities used in service communications. They are similar to business entities, but are specifically used for over-the-wire transmission. Think of similarities to how Fowler’s description of Data Transfer Objects is implemented.
[DataContract(
Name="Employee",
Namespace="http://samples.microsoft.com/contracts/2008/08")]
public class Employee
{
[DataMember]
public string Name { get; set; }
[DataMember]
public int PayrollNumber { get; set; }
}
This shows a simple Data Contract. Note that this is an entity – all the data it contains is intrinsically related, in that it describes properties of an Employee. The DataContract and DataMember attributes are used to decorate the class for the DataContractSerializer’s benefit.
Do also pay attention to the fact that I’ve used the Namespace parameter of the DataContract attribute – this is an absolutely key step in ensuring your versioning strategy is up to scratch. I should really have also implemented IExtensibleDataContract, as per Craig’s post on Versioning WCF Services. I won’t cover this in detail but do make sure you read up on this before diving in.
Message Contracts
So Data Contracts define entities – but our service doesn’t deal in entities! It deals in messages. Therefore Message Contracts group together Data Contracts to form meaningful and useful messages.
Usually each operation (i.e. method on a service) has two Message Contracts – a Request and a Response. One Way operations obviously have no Response message, but you get the picture!
[MessageContract(
IsWrapped=true,
WrapperName="AddEmployeeRequest",
WrapperNamespace="http://samples.microsoft.com/contracts/2008/08")]
public class AddEmployeeRequest
{
[MessageBodyMember]
public int DepartmentIdentifier { get; set; }
[MessageBodyMember]
public Employee Employee { get; set; }
[MessageBodyMember]
public Employee Manager { get; set; }
}
[MessageContract(
IsWrapped=true,
WrapperName="AddEmployeeResponse",
WrapperNamespace="http://samples.microsoft.com/contracts/2008/08")]
public class AddEmployeeResponse
{
[MessageBodyMember]
public bool Success { get; set; }
[MessageBodyMember]
public string FailureMessage { get; set; }
}
Here we see I’ve introduced an “AddEmployee” operation that our service will provide. I always use the “Request” and “Response” naming suffix convention to ensure that the intended use of these messages is clear. Message Contracts are also not reused like Data Contracts are; they are inextricably bound to an operation, and exist purely to define that operation and to allow versioning strategies to exist.
Note that we use the MessageContract and MessageBodyMember attributes to decorate our contract, and that again I have used the Namespace parameter to help with versioning. I always use “IsWrapped=true” to ensure maximum compatibility (see Using Message Contracts).
Members of the Message Contract can be either Data Contracts or primitive types – the example shows the use of both our Employee contract and an Int32.
Service Contract
The Service Contract brings together our Message Contracts (and therefore implicitly our Data Contracts) to use them to define operations, and to group operations together to form a service.
[ServiceContract(
Namespace="http://samples.microsoft.com/contracts/2008/08")]
public interface IEmpoyeeManagement
{
[OperationContract(
Action="http://samples.microsoft.com/contracts/2008/08/ É
IEmployeeManagement/AddEmployee")]
AddEmployeeResponse AddEmployee(AddEmployeeRequest request);
}
Note that in this case we’re using a .NET interface, not a class. We’re also using the ServiceContract and OperationContract attributes to decorate the interface. The Namespace and Action parameters to these attributes are used for versioning as usual.
Here you can see that my Request and Response messages are tied together by the Operation Contract definition for AddEmployee.
Service Configuration
The Service Configuration consists of many different things. I would like to define it as things that can be added to a service to customise the behaviour without requiring code or contracts to be changed... but unfortunately that isn’t quite true. For example, changing the InstanceContextMode can have a big effect on how you write your service. I guess this means that some specific areas of configuration and implementation are actually quite closely coupled, for good reason.
Anyway, configuration of a service includes things like the web.config settings (under <system.serviceModel>), and the use of the ServiceBehavior attribute. My service is so basic all I have in configuration is the default WCF web.config settings, so I’ll not bore you with that here!
Service Implementation
Well this one is pretty obvious, right? This is the meat of my service – the point of all these contracts, right? It’s the logic?
Nope.
I don’t mean to be so ruthless with this statement, but I just think it is important to understand. A service implementation is still part of the Service Interface – and it is purely responsible for translating between wire-format entities and business entities, maybe applying custom authorisation, message logging, exception shielding, and so on. It is almost an “adapter” layer that maps incoming messages onto the correct business logic – I firmly believe a service implementation should be very thin as a result of this, delegating most work to the business layer. The service implementation is not the business logic itself.
Let’s see a simple example implementation then;
public class EmployeeManagementService : IEmpoyeeManagement
{
public AddEmployeeResponse AddEmployee(AddEmployeeRequest request)
{
try
{
ITranslator<Employee, Person> translator =
Container.Get<ITranslator<Employee, Person>>();
Logic.SavePerson(
translator.Translate(request.Employee),
translator.Translate(request.Manager),
request.DepartmentIdentifier);
AddEmployeeResponse response = new AddEmployeeResponse();
response.Success = true;
return response;
}
catch (BusinessLogicException exception)
{
AddEmployeeResponse response = new AddEmployeeResponse();
response.Success = false;
response.FailureMessage =
ErrorMapper.SanitiseErrorMessage(exception);
return response;
}
catch (Exception exception)
{
SystemFailure failure =
ErrorMapper.SanitiseFailure(exception);
throw new FaultException<SystemFailure>(failure);
}
}
}
We can see our service implementation is a class that implements our service contract, and there is very little else of note other than the method code itself. So let’s inspect the method code and see what we find.
Firstly we have some entity translation. It is really common for a service implementation to need to translate from a Data Contract to a Business Entity, and therefore a simple yet consistent approach to this has been born. Consider the following implementations;
public interface ITranslator<From, To>
{
To Translate(From from);
}
public class EmployeeToPersonTranslator :
ITranslator<Employee, Person>,
ITranslator<Person, Employee>
{
public Person Translate(Employee from) ..
public Employee Translate(Person from) ..
}
These translators can easily be registered with a Service Locator (or we could use Dependency Injection or Dependency Resolution) as in my example, and retrieved with a call to a container.
Next we see our service implementation calls into some business logic, passing in translated entities and any additional data from the request message that is needed. Finally it constructs a success message and passes it back.
The other interesting part of this code is what happens in event of an error. My implementation is primarily designed to demonstrate a few different approaches, but the important point is that no error is returned to the caller without being “sanitised” first – i.e. I am applying the concepts of Exception Shielding. This ensures private data about my service (for example connection strings) is never exposed to the caller.
I’ve shown a few different approaches – using a return value in the response message, or using a Fault Contract (just a Data Contract used to communicate a fault) by throwing a new FaultException<T>. Fault Contracts should really be used in WCF if there is an unexpected error, but I do think there are some valid circumstances to use a “roll your own” response message; perhaps this is a topic for another post.
One point to note is that using this Fault Contract requires me to decorate my service contract with a FaultContract attribute;
[ServiceContract(
Namespace="http://samples.microsoft.com/contracts/2008/08")]
public interface IEmpoyeeManagement
{
[FaultContract(typeof(SystemFailure)]
[OperationContract(
Action="http://samples.microsoft.com/contracts/2008/08/ É
IEmployeeManagement/AddEmployee")]
AddEmployeeResponse AddEmployee(AddEmployeeRequest request);
}
Summary
Well that’s it – I hope this has helped you see how Service Interface fits together and what some of the benefits are. I’ve found that this approach helps with versioning, but also it helps to encourage a message-exchange approach to design instead of RPC (Remote Procedure Call).
What I mean by this is that services become designed to have course-grained interfaces, avoiding chatty calls. RPC is often seen like Java’s RMI – just calling methods on an object that happens to be physically located somewhere else – and this leads to forgetting about the costs of crossing service boundaries. Defining Data Contracts helps maximise reuse, and defining Message Contracts helps decrease granularity.
So now you love Service Interface just as much as I do, have a read of Don’s post regarding Message Contracts, and see what you think. I’m a firm believer in always using Message Contracts as I’m sure is obvious from this post, but make up your own mind.
This article is part of a series;
· WCSF Application Architecture 1: Introduction
· WCSF Application Architecture 2: Application Controller
· WCSF Application Architecture 3: Model View Presenter
· WCSF Application Architecture 4: Environment Abstraction
· WCSF Application Architecture 5: Defining Modules
· WCSF Application Architecture 6: Structuring Modules
Unfortunately it is also the worst named post in the series J
Introduction
It is a common requirement for customers to want to split web applications across physically separate tiers, usually using some kind of services technology. This post discusses some approaches to this using the Web Client Software Factory.
Although I focus on using WCF services, many of the concepts apply to ASMX and other technologies too – I have just chosen WCF as I believe it to be the best way to write services in the current .NET Framework environment.
* Note: Chances are I’m going to use the term Web Services a lot in this post. What I really mean when I say that is any kind of remote service – pretty much anything that can be written with WCF, for example.
Food for Thought
So first things first – let’s clear up some common myths.
1: SOA != Services
Just because your application uses Web Services (or any other kind of remote service), that doesn’t make it Service Oriented. It could still be just an app that uses Web Services. The current Wikipedia definition of SOA starts with a nice succinct statement about this;
“(SOA) is ... where functionality is grouped around business processes and packaged as interoperable services ... SOA separates functions into ... services ... which are made accessible over a network in order that they can be combined and reused in the production of business applications”.
In other words, if you’re writing a Web Service and Web Application as an inextricably linked pair that make up a single system, chances are you’re not doing SOA. SOA is an Enterprise Architecture, not an Application Architecture (although some applications will be built on the Enterprise Architecture by aggregating and reusing business services, and hence some apps are validly referred to as Service Oriented).
What this means to me is two things
1. Be pragmatic about what rules you follow when you are writing a completely isolated internal application.
2. Ask yourself this: “Why are we using a Web Service?” If your answer is “Because our company policy is that all new apps must be Service Oriented” (or something similar) I would recommend stepping back, and thinking deeply for a short while. How is adding a Web Service making your application Service Oriented? Is it really adding any value? If so, great – there are many valid reasons... but make sure you know what they are!
2: Services cost performance
Using a remote service is expensive (in terms of processing time, for example). If you previously had a method call that looked like this;
View.Orders = myBusinessLogic.GetOrders(user, startDate, endDate);
... and you move the implementation of GetOrders to be a remote Web Service, you will notice a significant performance degradation. Raw performance and scalability are often at odds like this! Suddenly we must serialize user information and dates, locate the remote service and open a channel, pass the data across a potentially unreliable network, spin up a service instance, deserialize the information, perform the business logic call that used to exist on the client, serialize the results, pass them back across the network, deserialize the results and turn them into a .NET list, and finally close the channel to the remote service. Phew. Now all that might be pretty fast in .NET, but it will be slower than an in-process method call.
Having said that, if the logic you must execute is expensive itself, you may find that removing load from the client Web Server and scaling it out to another physical tier improves the scalability of your system. I’m not saying don’t use services here – I just want you to be realistic about it!
3: RPC != Messaging
Because services add overheads, it is important to adopt a message exchange approach rather than a remote procedure call approach. What does this mean? Basically it comes down to two things;
1. Granularity. RPC consists of chatty, frequent calls between client and service, very quickly making it difficult to scale your system. When you think RPC, think of many systems written with Remoting or Java’s RMI. Message exchanges are courser grained and minimise the amount of calls and proportion of overheads involved.
2. Programming Model. I tend to find that RPC encourages the sharing of concepts internal to a service with the outside world. Use a message oriented approach makes you think about defining the contracts, abstracting where necessary, and encapsulating behaviour appropriately. Watch for a future post on the Service Interface pattern when I get a chance!
Candidate Architectures
So now that we’ve thought a little about what we want to avoid, let’s see a couple of approaches and discuss their characteristics.
1: Baseline
First up is our baseline architecture; this is what future examples will evolve from, and represents a basic WCSF application (ignoring splits across modules) without any kind of service layer.

Note that I’ve decided to expose my business logic here using a WCSF application service (not a web service). This communicates with my “model” (basically the business logic), which in turns talks to various data access classes (e.g. DbAccess). I hope that’s pretty straightforward.
2: Split Tiers
I nearly named this “RPC approach” because I feel that it encourages an RPC style of programming. Components above the dotted line are in my WCSF Web Application, and those below it are in the WCF Web Service.

What we have done here is just move the logic into a Web Service, and then change the WCSF application service that previously exposed business logic to purely act as a facade to the remote Web Service – in other words, it is a Service Agent or Service Proxy. This is a key concept – a Web Service is a resource, so if you are communicating with a Web Service directly in a class, you’re writing a resource (or data) access component.
The problem with this approach, in my opinion, is that this encourages developers to just call methods as though they were local to the web application, potentially leading to an RPC style system with very chatty communications and a serious scalability problem. Often people don’t realise that they are effectively writing an application that has no business logic layer (the Web Application)!! This is obviously contrary to well understood wisdom nowadays, and looking at the diagram above, I hope you see how unnatural it looks.
This lack of separation can also lead to changes in the service contracts affecting the UI. This is by no means ideal.
3: Remote Services
My preferred approach is shown below;
Here you can see that our missing logic layer has made a triumphant return! This might seem subtle but I think it completely changes class responsibilities and how your developers perceive the system. The logic in the Web Application is responsible for deciding when to go to a web service, or when to use a local cache, how to co-ordinate calls between different resources (you might have multiple web services!), when to enforce security or other policy, and so on. This then leaves your Resource Access layer able to dedicate itself to providing a real shield from the inner workings of the service calls.
As I’m sure regular readers have noticed, I’m a big fan of talking in concrete examples, so let’s see some (simplified) code that demonstrates this approach. Firstly, the Presenter and implied View;
public class MyPresenter<IMyView>
{
private ILogicService _logicService;
public MyPresenter([ServiceDependency] ILogicService logicService)
{
_logicService = logicService;
}
public void OnRetrieveOrders()
{
List<OrderEntity> results =
_logicService.FetchOpenOrdersForCurrentUser(
View.StartDate, View.EndDate);
View.Orders = results;
}
}
The key here is that the presenter is using a WCSF service (badly named as ILogicService) to fetch orders for display to the user. These orders are represented by an “OrderEntity” entity. Next, let’s see an example of an ILogicService implementation;
public class LogicService : ILogicService
{
private IAuthenticationService _authenticationService;
private IEntityTranslatorService _entityTranslatorService;
public LogicService(
[ServiceDependency] IAuthenticationService
authenticationService,
[ServiceDependency] IEntityTranslatorService
entityTranslatorService)
{
_authenticationService = authenticationService;
_entityTranslatorService = entityTranslatorService;
}
public List<OrderEntity> FetchOpenOrdersForCurrentUser(
DateTime startDate,
DateTime endDate)
{
OrderServiceProxy proxy = null;
try
{
proxy = new OrderServiceProxy();
proxy.Open();
proxy.LogOnService(CERTIFICATE_DETAILS);
string orderStatusCode =
proxy.GetOrderStatusCode(OrderStatus.Open);
List<Order> orders = proxy.GetOrders(
_authenticationService.CurrentUserName,
orderStatusCode,
startDate,
endDate);
List<OrderEntity> results =
_entityTranslatorService.Translate<Order, OrderEntity>(orders);
proxy.Close();
return results;
}
catch (Exception)
{
if (proxy != null)
proxy.Abort();
throw;
}
}
}
There are a few really important points to make here;
1. I have chosen to abstract environmental issues, such as authentication, away into a framework service. See my previous post on Environment Abstraction for more information on this.
2. All the management of the interaction with the service proxy is kept out of the Presenter, and instead is handled by our WCSF application service.
3. I am performing Entity Translation between the “Order” and “OrderEntity” objects. The former is actually part of the definition of the Order Service’s Service Contract, in that it defines how the remote service is communicated with. The latter is a Business Entity defined by my WCSF module. Therefore it is important that I expose the Business Entity not the proxy communication entity further up my architecture.
4. The service performs some limited Orchestration – it calls a number of methods on the service to achieve what is seen by the Presenter as a single business operation. Obviously I would prefer a very course grained service design, but I’ve done this to illustrate that this is the right place to perform any required orchestration (potentially across multiple services) and workflow.
5. The disposal of the proxy is done correctly. A “using” block is not the best way to deal with WCF proxies – see Avoiding Problems with the Using Statement.
6. This is also the right place for rich error handling, publishing, and compensation – please don’t follow my poor example in this respect J
7. I haven’t used the rich implementation of the Service Interface pattern I would usually, because constructing the messages would increase the volume of sample code and detract from the point. I’ll probably post about Service Interfaces soon, so watch this space!
The final important point is that this separation of business logic, resource access, entity translation, etc is likely to be repeated by the Order Service.
Potential Gotchas
When using WCF proxies there are a number of things worth knowing about. The first is the best way to use a “using” block, mentioned above.
Secondly, remember that a WCSF service is a singleton – so if you cache the WCF proxy you will be using the same one for every call, no matter which end user is browsing your site. No probs... oh, hang on! But what if you’re using a session-full binding? That would mean all your WCF calls would be using the same session, no matter which end user the call was for! This could certainly be a problem – so be very careful about this.
Thirdly, if you are caching your WCF proxy remember that a faulted proxy cannot be used again. So if your backend service fails and then comes back up, and you’re caching the proxy forever and for every user, your web application will be unusable until you cause it to flush the cache (e.g. by restarting the App Pool). The correct way to handle a faulted proxy is by adding the following code when creating it;
proxy = new OrderServiceProxy();
((IOrderServiceChannel)proxy).Faulted +=
new EventHandler(OrderService_Faulted);
In the event handler you can then react in some way – perhaps by Aborting the proxy and replacing it with a fresh one. This is obviously pretty academic for my example code above, but if you are caching proxies, consider this carefully. Also, if you don’t have a business logic layer, you might find it more difficult to deal with this kind of situation!
Finally, I’ve used the class generated by “Add Service Reference” in Visual Studio. It is actually pretty slow to new up one of these for every business operation when compared to using a cached Chann