WCF Multiple Contracts with Partial Classes

download code 

What are Partial classes?

Partial classes are classes that are split throughout several files (.cs), but are all of the same class. Most often this is used for things like generated code (like when you use Entity Framework and it generates all that fancy code to automatically make your table objects etc..). Partial classes are also used to hide all the generated code in many of the VS templates you create. Ever make a WinForm? WPF application? You probably never noticed it, but if you create a new WPF applications and double click in MainWindow.xaml.cs you have a class that looked like this:

     /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        
        public MainWindow()
        {
            InitializeComponent();
        }

    }
}

You’ll notice the class for this is a partial class for the MainWindow.xaml. Well, there you go. They are in places you have seen before and aren’t so mysterious. Without going into the details of this class specifically, the partial class here is hiding from you all the background work being done to define the events being triggered by button clicks, hover events etc… Pretty hot right? I thought so

Ok That’s Great, so when do partial classes apply to me?

Great question! There are a lot of reasons not to use partial classes and for good reason. Partial classes often create bad habits for developers because if used improperly, partial classes will extend a class that most likely should be divided out into another class/object all together. Even if it should be in the same class, breaking it up to gain you a few KB in the file is just silly and causes more headaches when you or another developer goes to it in six months to track a bug down!

So now i went through some reasons it is not a good idea and why it is bad practice to use them, so Gregg, why are you bothering to talk about them if I don’t need to use it? Good Question. Think Web Services and Multiple contracts. There are scenarios out there (I just ran into  one myself), where you have this master hub service internally that developers use for access third party applications or just other resources within the company through a web service. This web services primary purpose is to limit the amount of developers time being used to rewrite code. Yes I know that is being lazy, but lets face it, we wouldn’t be programmers if we weren’t lazy ;). Now, with that thought, you could very easily have the potential for needing to access multiple DALs and third party applications with this WCF Service. The logical thing would be to create a separate contract for each access layer right? Well, under normal conventions, doing this will require you to create a new WCF Service to along with that contract. In doing this, you have now forced the developer to consume a separate web service as a Service reference. This causes not only bloated auto generated code for each service reference created, but it also requires more maintenance on the developers side by needing to do an Update Reference on every consumed service every time a new feature is added to an one of several services/ contracts.

Now, with all that said, maybe that is acceptable to you or you want to give the developers that responsibility. In my case, I wanted very little need for consumption for each access layer and minimal maintenance on the developer. By taking all the contracts and consolidating them into one Service and separating each access layer by contract, you are keeping a separation of concerns, while still providing the developer with a single service endpoint to worry about. To me in the scenario I described, this is ideal and worth the extra effort.

Now you may be saying, “Gregg, I know C# can’t do multi-inheritance on classes, only interfaces right?”. Correct, but this is where partial classes do come to save the day.  Using partial classes, you will be able to inherit multiple interfaces and by separating the class into partial classes (each partial in a separate file), it will be much cleaner to read. So enough talk, lets code!

First Create a new WCF Service Application project. If you haven’t done this before, look up a tutorial on WCF start guides. This guide assumes you have at least created a WCF application before. Once the project has been created,  rename the Service file (svc file) to Master.svc.

** Note  ** Depending on the version of VS, you may have to right click the svc file and rename it in the markup as well. To do this:

1.) Right Click The service and select View Markup

image

If the Markup still has Service1, change it to Master.svc

image

Now that you have renamed the service name, go into the service itself and change the class to be partial and change the class name to GetData.This will be the class name that we will be making partial classes for. Next, go to your IService1 (the interface) and rename it to IGetData ( refractor the name when asked).Upon completion, your Master.svc file should look similar to this:

/// <summary>
/// This is the service file that is launched with the WCFTestClient and 
/// inherits 
/// </summary>
public partial class GetData : IGetData
{
 
}

and your interface should look similar to this:

[ServiceContract]
public interface IGetData
{

    [OperationContract]
    string GetSomeData(int value);

  
}

So at this point, you have a web service called Master and it inherits interface IGetData. This interface has a required method of GetSomeData. currently, the GetData class is not implementing t his method, so your code will not compile. Lets fix that shall we?

First lets create the second interface. Add a new interface called IGetData. Create a required method signature of string GetSomeData(int value);. Make sure to decorate the interface with the ServiceContract data annotation as well as OperationContract on the method signature. upon completion, your interface should look like this:

[ServiceContract]
public interface IGetData
{

    [OperationContract]
    string GetSomeData(int value);

  
}

 

Now lets create a new Class called GetData. This class is going to be another partial class that extends the GetData class. Just to make it known if it isn’t already, you cannot name multiple files with the same name (GetData for example), so anytime you create a new partial class inside another file, the file itself will have to have a new name, but the partial class will be the same name. This GetData partial class will inherit the IGetData interface and by doing so, must implement the method GetSomeData. Upon completion, this class should look like this:

/// Partial Class that implements the IGetData Interface
/// call GetSomeData. This partialClass is GetData which
/// is the same as the service class
public partial class GetData: IGetData
{

    public string GetSomeData(int value)
    {
        return "Service 1 Called";
    }
}

** Note ** Classes do not have to have the same name as the file itself, although for readability under normal circumstances, it should be standard practice. It should also be known that partial classes can in fact share the same file, but in our example we are trying to expand across files for the exact purpose of not overwhelming the developer who reads this later on.

Ok so now we have created our first extended class and inherited the interface. Lets do the second one.

Create a new interface called IDoMoreWork and make a method signature string DoMoreWork(). As you did with the interface, decorate the appropriate data annotation so that WCF knows it should be exposing this information to the clients. You interface should look like this:

[ServiceContract]
interface IDoMoreWork
{
    [OperationContract]
    string DoMoreWork();
}

Ok, we are almost there. Now as you may have guessed, we are going to make a new class called DoWork. This class file as the last one, will extend the GetData class using the partial keyword and inherit the IDWork interface. As before, by implementing the IDoWork interface, it must also implement the DoMoreWork method. When you are finished, you DoWork.cs class should look like this:

 

/// <summary>
   /// Partial Class that implements the IDoWork Interface
   /// call Do More work. This partialClass is GetData which
   /// is the same as the service class
   /// </summary>
   public partial class GetData :IDoMoreWork
   {
public string DoMoreWork()
{
    return "Service 2 Called";
}

You will notice that each method is very simple and only returns a string that signifies we are in a particular contract.

If you fire up the WCF Test Client, you should see that you consumed one service with multiple contracts, separating your methods into separate contracts for a more logical consumption.

 

image

 

The final piece of the puzzle is to add endpoints to the web.config file to tell the service that you really want the service to host both contracts. The only part of the web.config file that actually matters here is the services section. You want to add a new service with the name being the full namespace of the class being hosted. Then inside the service tag, you will define 3 endpoints that define both contracts and the exposure of the meta data for proper consumption. The final step will be to add a base address. This address defines to the service where the base location of the address it will be hosting and listen on.

See below for the code and comments.

<system.serviceModel>
<services>
  <!-- Define service and give it the namespace of the partial class-->
  <service name="FirstAttempt.GetData">
    <!--Add the IGetData contract as an endpoint to the service-->
    <endpoint address="" binding="basicHttpBinding" contract="FirstAttempt.IGetData" />
    <!--Add the IDoMoreWork contract as an endpoint to the service-->
    <endpoint address="" binding="basicHttpBinding" contract="FirstAttempt.IDoMoreWork" />
    <!--Add the metadata contract as an endpoint to the service for wsdl consumption-->
    <endpoint contract="IMetadataExchange" binding="mexHttpBinding" address="mex" />

    <host>
      <!--Add a base address so the service knows where exactly it is hosting from-->
      <baseAddresses>
        <add baseAddress="http://localhost:14890/" />
      </baseAddresses>
    </host>

    
  </service>
</services>

 

Why does this work?

So why does this work? Because the way WCF works is every interface that is declared as a Service Contract and has method signatures declared as an OperationContract is considered a NEW contract. Now, we are extending the class into separate files, but otherwise, we are only adding each interface to the service class that hosts everything, making it contain multiple contracts. You could for clarification, do the following in your Master.svc and not have a partial class:

/// <summary>
/// This is the service file that is launched with the WCFTestClient and 
/// inherits 
/// </summary>
public  class GetData : IGetData, IDoMoreWork
{
    public string DoMoreWork()
    {
        return "Service 2 Called";
    }

    public string GetSomeData(int value)
    {
        return "Service 1 Called";
    }
}

This would be completely legal, but if you think this could get rather large, but still want to keep the same nice flow for developers, the file could get big quick. This is why we went with partial classes for this.

 

Happy Coding :)!!

Advertisements

About Gregg Coleman

I am Senior-level Software Engineer working primarily these days with .NET. I have a good working knowledge of ASP.NET MVC, Web Forms, WCF web services and Windows Services. I spend much of my time in the Web Services (SOAP and REST) world in my current job designing and implementing various SOA architectures. I have been in the software engineering industry for about 6 years now and will not now nor ever consider myself an "expert" in programming because there is always so much to learn. My favorite thing about designing software is there are always new emerging technologies and something to learn every day! My current job has me spending much of my job on the bleeding edge of technologies and changing gears all the time, so I'm never bored and always challenged. On my spare time I enjoy weight training, reading and venturing to new places near by. Of course programing and learning new technologies are another hobby of mine.
This entry was posted in .NET, .NET 4.5, C#, Classes, Contracts, Interfaces, Namespaces, Operation Contract, Partial Classes, WCF and tagged , , , , , , , . Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s