Silverlight Hack

Silverlight & related .NET technologies

About Me

Welcome to Silverlighthack.com.  This is a site where you can find many articles on Silverlight, Windows Phone 7 and .NET related technologies.  

My name is Bart Czernicki.  I have been working with computers since 1988 and have over 12 professional years in the IT field focusing on architecture, technology strategy and product management.  I currently work as a Sr. Software Architect at a large software development company.

Below is the cover of my new book that shows how Silverlight's unique RIA features can be applied to create next-generation business intelligence (BI 2.0) applications.

Silverlight 4 Business Intelligence Soft 

Contact: bartczernicki@gmail.com

View Bart Czernickis profile on LinkedIn

NONE of the comments or opinions expressed here should be considered ofmy past or current employer(s).  The code provided is as-is without anyguarantees or warranties.

Silverlight enabled WCF Service Template is Bad Practice

Silverlight-enabled WCF Service  Template

Visual Studio 2008 SP1 with the Silverlight Tools includes a new template that makes creating a WCF service that can be consumed with Silverlight very easy.  Once you you have the Silverlight Tools installed, you can use the template when adding a new item:

Adding a WCF service based on this template does several things for us:

  • Like any other WCF Service template, this adds the refrences to all the necessary System.ServiceModel assemblies.
  • It adds a WCF endpoint based on the BasicHttpBinding (which is one of the three Silverlight supports natively); Modifies the web.config with the endpoint information.
  • Adds a class/contract baseline information to our service class.
  • The service can be consumed by a Silverlight 2 client with no other necessary configuration (excluding deployment considerations).

Let's take a look at the code that was generated from the service template:

namespace SilverlightApplication1.Web{[ServiceContract(Namespace = "")][AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]public class Service1{[OperationContract]public void DoWork(){// Add your operation implementation herereturn;}// Add more operations here and mark them with [OperationContract]}}

Above what we have is a public class called Service1 with one method DoWork().  The service is decorated with an attribute called ServiceContract (ServiceContractAttribute).  This tells the client what operations can be called on the service.  Applying the ServiceContract attribute on a class (or interface) exposes the type to service consumers.  WCF works on an opt-in model and methods need to explicitly configured to be exposed in the service.  This is what the OperationContract attribute (OperationContractAttribute) is for.  You apply this attribute on any methods that you want the client to be able to call through the service.  These two attributes are all that is needed to expose a service publicly. 

The problem with the template implementation is that it places the attributes directly on the class itself.  This obviously is a bad practice as it couples the service implementation and the class implementation together.  If you have read any architecture books/resources, this paradigm is not new to you.  Why is it bad for WCF?  When designing a WCF service, a developer needs to prepare for future use of the service and be ready for possible changes.  The more places you make changes causes the more items that could potentially break.  This could cause QA to be involved in re-testing certain parts of the program.  We obviously want to split this up so that the service design/contract (what types and what methods the service exposes) are seperated from actual implementation (what the DoWork() method does).  Another reason we want to break the contract and implementation is so that the contracts can be re-used on the client.  WCF includes a lot of gotchas especially when generating a proxy on the client.  What actually happens when you generate a proxy is that these types and the service exposed methods actually are generated on the client class inside the proxy.  You can mitigate lot of these issues by simply having the service contract types on the client. (I will cover this in another article; showing how to create an assembly that can be used both in Silverlight and .NET that shares service contracts).

Interfaces - The real Service Contracts 

By defintion, an interface is a contract that a class implementing has to adhere to.  Interfaces by definition fit the WCF structure very well here and we should define our service contracts (how the service will be designed) in our interface and then have our class implement this design.  You can see we are essentially factoring out the structure of our services all in our interfaces and then creating the actual implementation in our classes (how the service is going to do these operations).  In any WCF book you will read, it is stated over and over that the service/operation attributes should be placed on the interface rather than directly on the classes.

As you can see above, the template applied these service contracts directly on the class.  This is obviously a bad practice in WCF design.  Let's re-work the template above so we can create a service design that is factored outside of the implementation.  First, we can create an interface with one method DoWork() and apply the proper attributes and it will look like this:

using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.ServiceModel;namespace SilverlightApplication1.Web{[ServiceContract(Namespace = "")]interface IService1{[OperationContract]void DoWork();}}

Now we can refactor our Service1 class and simply implement the interface.  Notice I removed the ServiceContract and OperationContract attributes as they are now on the interface.  (Note: The AspNetCompatibilityRequirements attribute can ONLY be applied on a class, and this attribute is really there for backwards compatibility with ASP.NET and in true WCF rarely will you see it used).

using System;using System.Linq;using System.Runtime.Serialization;using System.ServiceModel;using System.ServiceModel.Activation;using System.Collections.Generic;using System.Text;namespace SilverlightApplication1.Web{[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]public class Service1 : IService1{public void DoWork(){// Add your operation implementation herereturn;}// Add more operations here and mark them with [OperationContract]}}

If you had followed the steps above, the service would not work when accessed.  The service will error and say that the contract could not be found.

 

When the template generated the WCF configuration, the ServiceContractAttribute was applied to on the class directly.  The service is looking for a type called Service1.  WCF and the configuration is not smart enough to know that we have an interface called IService1 and that Service1 is a class that implements that contract.  Therefore, we have to explicity give the name of the class or interface that has the ServiceContractAttribute applied to it.  In our example, this is the IService1 interface.  We simply need to change service configuration inside the web.config from this:

<service behaviorConfiguration="SilverlightApplication1.Web.Service1Behavior" name="SilverlightApplication1.Web.Service1">

  <endpoint address="" binding="basicHttpBinding" contract="SilverlightApplication1.Web.Service1"/>

  <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>

</service>

to this:

<service behaviorConfiguration="SilverlightApplication1.Web.Service1Behavior" name="SilverlightApplication1.Web.Service1">

  <endpoint address="" binding="basicHttpBinding" contract="SilverlightApplication1.Web.IService1"/>

  <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>

</service>

Summary

The Silverlight-enabled WCF Service Template is a nice way to get started with implementing a Silverlight-based service.  However, because the contract definitions are directly applied to the class, it should not be used as guidance on how one should lay out their WCF design.  As you saw above, it is quite easy to refactor the service design from the implementation in a couple of steps.  This allows your WCF service to follow WCF best practice guidelines.  The template is a good starting point for starting a Silverlight WCF project but only after refactoring the initial contract.  In the next article I will show how to refactor the contracts into an assembly both the service and the client (service consumer) can share.

 

kick it on DotNetKicks.com
Posted: Dec 04 2008, 15:37 by Bart Czernicki | Comments (6) RSS comment feed |
  • Currently 3.666667/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5
Filed under: Silverlight | WCF
Tags:
Social Bookmarks: E-mail | Kick it! | DZone it! | del.icio.us
blog comments powered by Disqus