Sharing DataContract across WCF Services without distributing separate copies to the client


Problem Statement:

Consider a scenario wherein we have two WCF services, one fetching the details of employees and the second one updating these details to the database, and both sharing the same DataContract.

When trying to add the references of both the services in the client, we can’t share the same namespace as the following error occurs.

Cannot create a service reference with the namespace ‘namespace’ because the name is already in use by an existing service reference, folder or file.

Providing a separate namespaces while adding references of the services means we are distributing separate copies of the DataContract. Hence a better solution is needed.

Solution:
To resolve this issue we need to share the DataContract across multiple services without distributing multiple copies of the DataContract to the client.
For that we need to compile the DataContract into its own assembly and then distribute this assembly to the client.

Following is a step-by-step guide from Service creation to consuming it, in order to achieve the solution.

1. Create a new Class Library Project name it [namespace].[BusinessModel] and your solution should look like this:

This is the DataContract we’re going to share across services.

2. Add a new WCF Service Application to the existing solution and name it as [namespace].DataReaderService and now the solution should look like this.

This is the first service that will share the DataContract

3.  Add the second WCF Service Application name it [namespace].DataUpdater and now the solution should look like this.

This will be the second service that is going to share the DataContract.

Now we are going to extract the DataContract from the assembly [namespace].[BusinessModel].
To achieve this we will use the following command

svcutil /dconly <path to the output DataContract class library dll>

/dataContractOnly: Operate on Data Contract types only. Service  Contracts will not be processed. (Short  Form: /dconly)

4. Open a Visual Studio command prompt and execute this command, the command and the output is shown below.

The svcutil /dconly command extracts the DataContracts from the given assembly and creates a number of .xsd files. These .xsd files can be distributed to the service consumer teams around, that will consume and use theses DataContracts.

5. Now from these .xsd files we need to use one whose name is same as of our DataContract assembly  to generate a class file to be included in the client project.

So let’s do this. in the following command the out parameter decides the name of the class file to be generated. Use the following command.

svcutil /dconly /language:CS Paxcel.Administration.BusinessModel.xsd /out:Paxcel.Administration.BusinessModel.cs

The command and the output is shown as given in the following image.

6. Now add a new Class library Project in this solution and name it as [namespace].[BusinessModel], remove the class1.cs file and add the [namespace].BusinessModel.cs file to this project, add reference to System.runtime.Serialization and our solution should look like this.

7. Now lets add a Windows Forms Application name it [namespace].Client and in this project add a reference to the [namespace].Client.BusinessModel project

8. Next, while adding reference to the service click on the Advanced… button, Select Reuse types in the specified referenced assemblies as shown in the following image.

9. Repeat these steps while adding reference to the second service.

Now both of the services at the client side will be using the same DataContract.

No casting is needed and the client code will be very clean and nice.

Now we’re done, it is now possible for the consumer to make calls to the services like this

Leave a Reply

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


nine × = 18

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>