Monday, November 17, 2014

WCF – Service contract in a different project


I strongly recommend to implement service contracts in a separated project, why? Because in some scenarios I will need to share my contracts with external client applications, just because adding a "Web reference" is not a good idea, I agree it is easy, fast and can be updated from Visual Studio, but generated code is not managed by the developer & modify it is just a bug itself.
When adding a WCF Service application to your solution, your new project will looks like this:



The Visual Studio template has done all the job for you:
  • IService1 contains the service contract
  • Service1.svc.cs is the service it self
Ok, thanks Visual Studio for your help, but I prefer to do it by myself. First of all, "Service1" is not a proper name for a service, just remove the items generated by the Visual Studio and add a new WCF Service to your project (BusinessService in this example):



Once again, Visual Studio try to help me adding service contract and the service implementation in the project. This is not what I want so, I'm going to remove the IBusinessService, as I want it to be declared in a different project.
Add a new project "ToAllMicrosoftDevsOutThere.Service.Contracts" to your solution, the implementation of your service contract will be there, including DataContracts and MessageContracts. Following references must be added to your contracts project:
  • System.ServiceModel
  • System.Runtime.Serialization (for DataContracts/DataMember)
My service will contain just one operation (by now), defined on the service interface IBusinessService, which looks like:


[ServiceContract]
public interface IBusinessService
{
   [OperationContract]
   DoWorkResponse DoWork(DoWorkRequest request);
}

 

There are two interesting things on this interfaces:
  • My service interface must have the attribute 'ServiceContract'
  • All my service operations must have the attribute 'OperationContract'
Next step, my Service can receive complex objects as requests and send complex responses. These objects usually named DTO (Data Transfer Objects), should not contain any business logic, only properties (get/set) containing all the data my service needs in order to provide a response. For defining these DTO I will use MessageContracts:


[MessageContract]
public class DoWorkRequest
{
   [MessageBodyMember]
   public BusinessObjectDto BusinessEntity
   { get; set; }
}


[MessageContract]
public class DoWorkResponse
{
   [MessageBodyMember]
   public bool ItWasOk
   { getset}
}

 
In the previous code, I'm already using a DataContract (a data contract is a complex data type in my message contract):


[DataContract]
public class BusinessObjectDto
{
   [DataMember]
   public string Name
   { getset}
}

 
I need to add a reference to my contracts project on my service project and, now my projects structure looks like:



After adding the reference to my contracts project I can implement my Service contract on my service like follow:


namespace ToAllMicrosoftDevsOutThere.Service.Host
{
   public class BusinessService : IBusinessService
   {
      public DoWorkResponse DoWork(DoWorkRequest request)
      {
         return new DoWorkResponse() { ItWasOk true };
      }
   }
}

 
And that's all, just taking some minutes doing the setup of my WCF Service, I will be able to provide my Contract in a single DLL to any external application (.NET client…)
Enjoy coding!

No comments:

Post a Comment