Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

WCF Multiple Contracts

Could I please get some clarification on a complex WCF service that exposes my business objects. Let's say I have 4 objects: contact, organisation, project and letter.

Is the best way to create my service:

  1. Make 4 contracts as 'service objects' and pass the object and the intended operation as values/parameters in the 'service object'? or
  2. Create contracts for all of the objects and their functions (which could be many)?

Many Thanks,

Chris

like image 822
Christopher Leach Avatar asked Jan 19 '23 09:01

Christopher Leach


2 Answers

According to the Interface Segregation Principle, you might want to think about splitting those things up.

One typical approach is to have one interface (e.g. one "service") per object type - e.g. one interface for Contact with all the operations needed and useful for contacts, etc.

Of course, you might also have methods that deal with multiple different types of objects - those are a bit tricky to place in a specific service contract.

Also, with WCF, you can easily have a single service implementation class that then in turn implements multiple of those interfaces at once - e.g. to use common code or common patterns.

But I guess it would be a good idea to rethink your service contract and convert it into smaller, more manageable chunks.

Update:

if your service implementation class implements four service contracts, then you'd have to configure it like this:

<services>
  <service name="YourNamespace.YourServiceImplementation">
     <host>
        <baseAddresses>
            <add baseAddress="http://YourServer/MyServices/" />
        </baseAddresses>
     </host>
     <endpoint name="Contact"
         address="Contact"
         binding="basicHttpBinding"
         contract="YourNamespace.IContactService" />
     <endpoint name="Letter"
         address="Letter"
         binding="basicHttpBinding"
         contract="YourNamespace.ILetterService" />
     <endpoint name="Organisation"
         address="Organisation"
         binding="basicHttpBinding"
         contract="YourNamespace.IOrganisationService" />
     <endpoint name="Project"
         address="Project"
         binding="basicHttpBinding"
         contract="YourNamespace.IProjectService" />
     <endpoint name="mex"
         address="mex"
         binding="mexHttpBinding" 
         contract="IMetadataExchange" />
  </service>
</services>

Now, each of your services is available at a specific endpoint:

  • your IContractService is reachable at http://YourServer/MyServices/Contact
  • your ILetterService is reachable at http://YourServer/MyServices/Letter

and so on....

For each of those addresses, you can now add service references from a client - add only those you really need. One app might need only a single of those services, another might need two or three etc.

like image 132
marc_s Avatar answered Jan 24 '23 18:01

marc_s


Just to add to the very helpful answer by Marc, the interfaces need to be decorated as below and then only we get the chance to add an independent reference to each contract implemented by the service separately.

[ServiceContract(Name="Contact", Namespace="YourNamespace.IContactService")]
public interface IContractService
{
   ...
}

Similarly for other interfaces

[ServiceContract(Name="Letter", Namespace="YourNamespace.ILetterService")]
public interface ILetterService
{
   ...
}

Without adding these attributes, I was unable to add separate service refernce to each of the contracts implemented by the common service.

like image 28
Naresh Mittal Avatar answered Jan 24 '23 18:01

Naresh Mittal