In a previous article, Multiple web service references sharing types, I wrote about sharing types between referenced web services. That article used the old ASP.NET Web Service technique, but nowadays WCF is the technology to use. In this article I will use much the same scenario as in the previous article, Visual Studio 2010 and of course WCF (.NET 4).
I will describe the scenario below, describe what may be an upcoming problem and what can be done to avoid it. Please read the previous article as well, it is much the same solution that is to be presented here.
If you are not familiar with WCF and DataContracts you can read David Chappell’s article here: Introducing Windows Communication Foundation in .NET Framework 4. Aaron Skonnard has written a great article about WCF 4, read it here: A Developer’s Introduction to Windows Communication Foundation 4.
The scenario
Let’s consider the following scenario:
One WCF service exposes a number of methods, in this example there will be only two:
- GetCustomer: takes as parameter an integer, an ID of a customer, and returns the customer with that ID from the repository.
- GetCustomerStatus: takes as parameter a customer and returns a string based on the age of the customer that tells the client whether the customer is allowed to place orders or not.
The interface exposed by the service is shown below. Please note the attribute [ServiceContract] on the interface and [OperationContract] on the methods.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;
using ServicesDataContracts;
namespace CustomerService
{
[ServiceContract]
public interface IHandler
{
[OperationContract]
Customer GetCustomer(int id);
[OperationContract]
string GetCustomerStatus(Customer c);
}
}
These two methods uses the same DataContract. A DataContract in the WCF world is a class defining a type exposed by the service. This class may contain a lot of stuff, methods and functions. The properties to be exposed to the consumers are marked with an attribute, [DataMember]. These properties may include logic in their get and set methods. The Customer DataContract is shown here, see the comments below the code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.Serialization;
namespace ServicesDataContracts
{
[DataContract]
public class Customer
{
[DataMember]
public int ID { get; set; }
[DataMember]
public string Name { get; set; }
[DataMember]
public DateTime BirthDate { get; set; }
///
/// True if the customer is 18+ years old, false otherwise.
///
public bool IsAllowedToShop
{
get
{
if (DateTime.Now.Date.AddYears(-18) >= BirthDate.Date)
return true;
return false;
}
}
///
/// Returns a text based on the age of the customer.
///
public string GetStatusMessage()
{
if (IsAllowedToShop)
return string.Format(
"[{0}] {1} is allowed to place orders",
this.ID, this.Name);
return string.Format(
"[{0}] {1} is NOT allowed to place orders. Reason: too young, born {2}.",
this.ID, this.Name, this.BirthDate.ToShortDateString());
}
}
}
Some notes on the code above:
- I have decided to place the Customer class in a separate class library, the namespace is therefor ServicesDataContracts.
- On line 5: the System.Runtime.Serialization namespace contains the DataContract attribute. Please note that it is also required to add a reference to System.Runtime.Serialization to use the DataContract attribute.
- The DataMember attribute is added to the properties to be exposed by the service DataContract. In this example these properties are ID, Name and BirthDate.
- The property IsAllowedToShop is not exposed.
- The function GetStatusMessage is not exposed.
- The properties exposed by the DataContract may contain logic in the get and set methods, but this is not transferred to the client when adding a service reference to client project.
A consumer of the service and the DataContract above may look like this:
CustomerService.HandlerClient customerClient = new CustomerService.HandlerClient(); CustomerService.Customer customer1 = customerClient.GetCustomer(1); string statusText = customerClient.GetCustomerStatus(customer1);
This consumer holds a reference to the service through the CustomerService namespace. The namespace is defined when adding the service reference.
So far the service interface is small and tiny, but it will for sure grow over time. It comes to a point when it is hard to maintain the service and therefor it may be necessary to split it into a number of smaller services. Take a look at the picture below, it may make things clearer what I want to do with the WCF Service.

The service consumer shall be able to pass objects from one service to another, without any casting.
The split and types sharing
The scenario stated above is trivial and the service interface is small, but still let’s have a look at how to split it. The same procedure when splitting is probably applicable on larger services with a lot of DataContracts. The following will be done:
- Create a service exposing the GetCustomer method. This service holds the customer repository, in this case it will be a fake repository.
- Create a service exposing the GetCustomerStatus method.
- The two services will use the same DataContract, the Customer class shown above.
- Create a DataContract to be distributed to the client(s) (I will describe why below).
- Create a client application, referencing the two services.
So why should the DataContract be distributed separately to the service consumers? When adding service references to the two services created, the Customer class will be of different types depending on what service the client will use. This makes it harder to get a customer from the service exposing the GetCustomer method and pass this customer on to the service exposing the GetCustomerStatus. The customer returned by the first service must be casted to a customer object type handled by the second service. In this example the customer class is small, but it would still be nice to just be able to pass the object on to the next service.
The first two things in the list above is easy, add two WCF Service Applications to the Visual Studio solution. Add the methods from the interface above to the new services, the GetCustomer method goes into the first interface and the GetCustomerStatus method goes into the second one. Both services need to reference the DataContract class library, the same library used above. After that, compile the solution.
The trick to make the services share the same types on the client side is to have the DataContract in a separate class library. This makes it possible to use the svcutil tool that comes with Visual Studio. With that tool you can extract the DataContracts defined in a class library, so let’s do it.
DataContract extraction
Open a Visual Studio command prompt and execute the following command, the output is shown below:
svcutil /dconly <path to the output DataContract class library dll>

This command will extract the DataContracts from the .dll file and create a number of .xsd files. The .xsd files can be distributed to the service consumer teams around, that will consume and use theses DataContracts. In this example I will use the .xsd file with the same name as the DataContract class library .dll file and generate a class file to be included in the client project. So let’s do this. Note that the .xsd file in my case is called ServicesDataContracts.xsd since the class library holding the contract is called ServicesDataContracts. The out parameter lets us decide the name of the class file to be generated. The output is shown below.
svcutil /dconly /language:CS ServicesDataContracts.xsd /out:CustomerDataContracts.cs

The class file generated by the above command line is added to a client side class library project. In my case I decided to call this project ConsumerDataContracts.
Adding service references
Now it’s time to add service references to the two services created above. But before that, let the client application reference the class library where the ConsumerDataContracts class was added. The solution will look like this:

There you can see the DataContracts class library and the reference to that from the ServiceConsumer project. In my case I used a Windows Forms application to consume the services.
Now it’s time to add the service references. Right-click and select “Add Service Reference…”. Enter the address to the first service, give it a namespace of your choice (I entered “CreatorService”), click the Advanced button and make sure to select “Reuse types in specified referenced assemblies” and after that select the ConsumerDataContracts reference. This looks like this:

Click OK. The service reference will now be added to the project. Repeat these things adding a reference to the second WCF service. I called the second service reference ControllerService. The solution will now look like this:
Since we added the services with the reuse types settings like this, the two service references will use the Customer DataContract in the ConsumerDataContracts.
Now we’re done, it is now possible for the consumer to make calls to the services like this:
CreatorService.CreatorClient creatorServiceClient = new CreatorService.CreatorClient(); Customer customer1 = creatorServiceClient.GetCustomer(1); ControllerService.ControllerClient controllerServiceClient = new ControllerService.ControllerClient(); string statusText = controllerServiceClient.GetCustomerStatus(customer1);
Some notes on the code above:
- On line 1 and 2: The CreatorService client is created
- On line 3: A customer object is returned from the CreatorService
- On line 5 and 6: The ControllerService client is created
- On line 7: The customer object is passed to the ControllerService
The service method invocation on line 7 wouldn’t be possible, it would generate a compilation error, if we hadn’t reused the types when we added the service references earlier.
What just happened?
I will try to summarize what we have done:
- We wanted to split an existing WCF service into smaller parts.
- We wanted the smaller services to share types on the client side
- We created two smaller services using the same datacontract class library as the larger one
- We extracted the datacontracts and added them to a client class library project
- We added service references to the client project and let them reuse types from the client class library project where we added the extracted datacontracts
- We tried the services out by getting a customer object from one service and pass this on as a parameter to another service
No casting is needed and the client code will be very clean and nice. The code on the service side is exactly the same as before the split, the only difference is that half the code goes into one service and the other half goes into the other service.
As soon as I have solved the problems to attach files to a post, I will publish the solution I used to try this out. This solution contains both the service before and after the split. The service consumer consists of two forms, one that uses the “large” service and one that uses the two smaller services.


Hi, I was searching a page of best softwares on the internet and i found a google blog , so nature and usefull blog . Also , many software is free . I liked that page and i advice to all of you :http://oncowepa.blogspot.com/
This doesn’t work, simply the service reference regenerates the proxy classes in the client again ignoring the reuse types…
I agree with Asela, this scenario doesn’t work …
It worked great for me! Thanks!
please upload sample files…
Doesn’t work for me either…very frustrating. I wonder if it is a Visual Studio SP1 issue
Your scenario wouldn’t work, if consumer will not have a copy of ServicesDataContracts.DLL.
I’m extremely impressed along with your writing skills as neatly as with the structure on your weblog. Is that this a paid subject matter or did you customize it your self? Anyway stay up the excellent high quality writing, it is uncommon to look a nice weblog like this one today..
Really good article. but it is concidering CollectionDataContracts . i added service reference , it is referening the contractassembly for the DataContracts but it is creating classes for the CollectDataContract eventhough if it is available in my contract assemblt
.
This is really a nice post. But a question – why do you need to extract DataContract from the DLL if you have distributed the DLL to consumer side? Looking forward to your reply. Thanks a lot for your excellent blog.
I think we should user
svcutil.exe /dCOnly /language:CS *.xsd
instead of
svcutil /dconly /language:CS ServicesDataContracts.xsd /out:CustomerDataContracts.cs
Indeed a very educative and nice article thanks. I am working on a scenario that is a mix of your both articles i.e.” Using interfaces when implementing web services” and “Sharing DataContracts between WCF Services” , somehow it is not working, the exact scenario is to coonsume a WCF service and ASP.net Webservice using a common proxy i.e.
ASP.Net Webservice
CommonConsumer (To Consume using sameproxy)
WCFWebservice
As an Example (referring to the same example in your aricle Using interfaces when implementing web services)
The WeightCalculator should be able to consume
i) TypeACalculator webservice that is a ASP .net webservice
ii) TypeWCFCalculator WCF webservice
using a single proxy.
I have tried creating multiple bindings of different types in order to make WCF service same as ASP.net Webservice but no luck.
Thanks in advance for your suggestions and inputs
Awaiting inputs and suggestions
@Kumar K for using collection types ex:
[CollectionDataContract(Name = "DataObject")]
public class DataObject : Dictionary
{
}
you need to add this to ServiceRefrence.svcmap file
Hope it helps…
The code didn’t show above, hope now I see it