This MessageHeader will self destruct in 5 seconds

Let’s get our hands dirty with an example you can follow along with. With the basic concepts covered we can whip up something to send some data back and forth. We will start with a simple winform to run our service. Another winform (acting as the client application) to connect to it so our service can do some intended job.

In this post I’m also going to introduce a refined and well developed library of enhancements for WCF. It is created by the very talented Juval Lowy you can find his work at IDesign.net. This library is called ServiceModelEx it is available as a free download, and it is very, very useful. I hope to demonstrate its usefulness in this and future posts. ServiceModelEx is designed to help simplify some of the more complex aspects of WCF along with adding extension to existing features. It makes some aspects of WCF more robust, such as adding TypeSafe alternatives and often adding an overlooked sub-feature (e.g. NetNamedPipeContextBinding I’ll discuss this in a future post).

Once you have ServiceModelEx downloaded and included in your Visual Studio project all you need to do is add a reference to it:

//WCF Service Model:
using System.ServiceModel;
//iDesign Service Model Extensions:
using ServiceModelEx;

In this post I’m introducing a theme for the demos; they will follow the ideas of a medical system. With concepts such as Patient, TreatmentSchedule, MedicalProcedure, Doctor, and other types of system Users (Nurses, LabTechnicians, etc).

On with it.
We are setting up a simple call to a service to create/update/delete a new patient.

To begin we will need to setup some data constructs (they are simplified to keep the code sections short, i.e. no extensive code to setup private members and public properties). A class MsgHeader will act as a common object sent ‘out-of-band’ on all calls to the service. The ‘out-of-band’ concept is used for the purpose of keeping data contracts free of plumbing-related operations. This example uses the header to supply something specific about the user, and the type of operation we are performing (enum OperationTypes). Another example of advanced control data you can pass via headers is a ‘message priority’ value.

[DataContract]
public class MsgHeader
{
    [DataMember]
    public int userRoleId;
    [DataMember]
    public int operationType;
}

A snippet of the data contract, and other setup data:

[DataContract]
public class Patient
{
   [DataMember]
   public int PatientId;
   //more members...
}

public enum OperationTypes { 
   Update = 0, Insert = 1, Delete = 2 }
public enum UserRoles { 
   Reception = 1, Nurse = 2, Doctor = 3 }

The Service is set up with a simple save/retrieve interface:

[ServiceContract]
interface IPatientContract
{
   [OperationContract]
   void SavePatient(Patient p);
   [OperationContract]
   Patient RetrievePatient(int patientId);
}

Via the Client proxy constructor we pass in our populated MsgHeader object. Then call any required methods on the proxy, in this case the save.

//class instance of patient details
public Patient CurrentPatient;

public void Save()
{
   MsgHeader header = new MsgHeader();
   //Set the properties accordingly ...

   //Setup and Call Proxy
   MedicalSystem proxy = new MedicalSystem(header);

   proxy.SavePatient(this.CurrentPatient);

   proxy.Close();
}

Finally on the service implementation to access the MsgHeader you simply use HeaderContext.Current.

class MedicalSystem : IPatientContract
{
   public void SavePatient(Patient p)
   {
      switch (HeaderContext.Current.dataOperation)
      {
         case (int)DataOperations.Delete:
            DeletePatient(p.id);
            break;
         case (int)DataOperations.Insert:
            CreateNewPatient(p);
            break;
         // ...
      }
   }
   // ...
}

There we have it – ‘out-of-band’ passing of data to your service to keep system entities free of the clutter of control data.

Advertisements