.NET and me Coding dreams since 1998!

1Nov/096

Design for testability – WCF proxies

Recently I spent some time participating in projects involving Silverlight, Prism etc and there are couple of interesting things I’ve came up with during that period which I would like to share with the community in a form of a couple of blog posts showing the “enhancements” I did in our Prism based implementation.

I was thinking a lot where to start and as a result of that I have decided to start with something small but useful. I’ll focus in this blog post on Silverlight, but this simple trick is usable in any other client technology making WCF calls. So, here we go…

How to have testable Silverlight code depending on WCF calls

Why reinventing the wheel?

In order to make sure that trivial thing I’ll be writing about today was not already covered by someone I did my Bing homework and came out with two approaches you might want to check out:

While I find both of them to be perfectly acceptable solution I think they are suboptimal due to different reasons.

In case of first solution (which based on screen cast comments is the way a lot of people do) there is one more layer of abstraction to be maintained.
In typical DDD style application we have DB tables mapped to domain entities which are (usually) flattened in web server layer where the WCF service contracts behave as application level services with client centric shapes and behaviors. With this approach we need another interface with either its own behaviors or just copy pasting the service contract and additional adapter class which delegates the calls to proxy. IMHO, layer of abstraction down –> maintainability level up :)

In case of second solution, my objections are similar to the one I have regarding service locator. Abstracting the “locator” (servicehost) leads to opaque dependencies on a consumer level which are much harder to be unit tested and understood. On top of that, I find this solution also to introduce additional complexity with defining factories, providers etc is IMHO are overkill for simple “TDD enable WCF proxy dependable code”

Duct tape programmer solution

Regardless of how much I disagree with Joel on the value of the duct tape programmer, I couldn’t get away from the fact that my solution compared with other two (full of big patterns and cool code) looks exactly like it is been done by the duct tape programmer – me. :) That’s ok, simplicity is #1 design criteria for me.

In this solution I won’t be using therefore any patterns but instead I would just rely on one hack and one small convention to get quickly testable code which is easier to be maintained and understood (compared to other approaches).

Demoware “WCF proxy being called directly” sample

image So, here’s the setup for today post. We are having application which goal is to show the names of the users having salary greater then $1000.

Client is implemented using Silverlight accessing the user data on a server side by making a WCF service calls.

In order to do that I used vanilla Silverlight solution (didn’t want to use Prism here) consisting of two projects:

  • Web application containing a UserService.svc WCF service and hosting a silverlight app.
  • Silverlight application which has UserService service proxy and MainPage showing the names of users in a ListBox.

 

 

UserService.svc

using System.Collections.ObjectModel;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Activation;

namespace SilverlightApplication.Web
{
    [ServiceContract(Namespace = "http://blog.vuscode.com/200911")]
    [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
    public class UserService
    {
        [OperationContract]
        public Collection<User> GetUsers()
        {
            return new Collection() 
            { 
                new User { Id = 1, Name = "Nikola", Salary = 1000 },
                new User { Id = 2, Name = "John", Salary = 2000 },
                new User { Id = 3, Name = "Jane", Salary = 3000 },

            };
        }
    }

    [DataContract]
    public class User
    {
        [DataMember]
        public int Id { get; set; }

        [DataMember]
        public string Name { get; set; }

        [DataMember]
        public decimal Salary { get; set; }
    }
}

Nothing important here: In one file OperationContract defining a method GetUsers returning the collection of users (User DataContratct being defined in the same file)

Let’s move on…

MainPagePresenter? Where’s the MainPageViewModel?

Well, I was surprised that many people I spoke with recently think MVVM is not the only “right” way to do SilverlightWPF development and I tend to disagree with that. While MVVM has its own values (it is also presentation pattern of my choice too) you can do MVC or MVP (both passive view and supervising controller) equally successfully like you can do it in desktop applications (speaking of which, Silverlight for me is desktop app deployed through browser) If you don’t trust me, ask Jeremy. That’s why I ended with some implementation for this

So, in order to spice up this blog post a bit I ended with MVP- like implementation with MainPagePresenter implemented like this

using System.Windows;
using SilverlightApplication.UserServiceProxy;
using System.Linq;

namespace SilverlightApplication
{
    public class MainPagePresenter
    {
        private FrameworkElement view;
        
        public MainPagePresenter(FrameworkElement view)
        {
            this.view = view;
        }

        public void Init() 
        {
            UserServiceClient proxy = new UserServiceClient();
            proxy.GetUsersCompleted += (sender, e) =>
                                       {
                                           this.view.DataContext = e.Result.Where(p => p.Salary > 1000);
                                       };
            proxy.GetUsersAsync();
        }
    }
}

Constructor here is more interesting because it accepts the instance with type inheriting from FrameworkElement (pretty much most of controls in Silverlight) and stores its pointer to a view filed. In other words, abstraction of a view is being injected into the presenter just instead of the IView I am being smart here and using the FrameworkElement as abstraction  every view (user control implements).

It is the good old demoware type of code you’ve seen on a lot of places with proxy being instantiated in the method body spiced up with cool lambda implementation of async event handler (which any better presenter would use to scare the session attendees) and with a simple linq statement filtering the result set to exclude the rows lower then 1000.

The magic in this code starts when view FrameworkElement.DataContext gets set by the filtered result set. Presenter doesn’t have a clue about what specific control view is but still it is able to set its common property to a value generating desired view behavior.

Wiring  up the view and the presenter

There’s really big religious war on the IT sky regarding who is created first (view or viewmodel presenter) and the allowed level of coupling between them. I have my own take on that to which I would dedicate a separate blog post (it is important subject) but for the sake of this blog post let say that it is perfectlly fine that view is created first and that it has direct reference to presenter.

That’s how the view (MainPage.xaml file) ended being implemented like this

using System.Windows;
using System.Windows.Controls;

namespace SilverlightApplication
{
    public partial class MainPage : UserControl
    {
        MainPagePresenter presenter;

        public MainPage()
        {
            InitializeComponent();
            this.presenter = new MainPagePresenter(this);
            this.Loaded += new RoutedEventHandler(MainPage_Loaded);
        }

        void MainPage_Loaded(object sender, RoutedEventArgs e)
        {
            this.presenter.Init();
        }
    }
}

As you can see in a page constructor a instance of the presenter was created with a pointer to the page itself being passed to presenter (which if you look up would be held as a presenter field and used in Init method).

Then Loaded event handler is being created (don’t put any UI related code in the constructor because it is not guaranteed that UI would be ready when that line would be executed) and in it presenter.Init() method invoked. In other word, view said to presenter “Please set me up!”

Markup code

Did I tell you how much I like WpfSilverlight? Check the simplicity of the markup code!

    <Grid x:Name="LayoutRoot" Background="White">
        <ListBox
                 Name="listBox1"
                 ItemsSource="{Binding}"
                 DisplayMemberPath="Name" />
    </Grid>

Setting ItemsSource to {Binding} effectively said to control “Bind to your own DataContext” (key moment specific to WPFSL), and DisplayMemeberPath Name value can be read “whatever the collection would be in DataContext, collection item would have a property called Name”

Simple, elegant and powerful!

Runtime experience

image

Wow, so much talk about such a simple thing. Ok, I proved it working

My duct tape based solution

is based on the simplest possible solution I was expecting that WCF supports out of box: IXYZServiceClient interface contracting in abstract way proxy behavior. 

To my surprise I have realized that WCF generated proxy is not creating that interface (IUserServiceClient in this example) so I decided to created in manually.

Doing things WCF team should have already done

I’ve clicked on Show All files icon (to see hidden proxy files) and opened Reference.cs file containing proxy c# code.

image

Then I found UserServiceClient class definition

image

Right click it and pick to extract interface (R# can help with this too)

image

I pick only the members I care to be abstracted (leaving unchecked all of the WCF infrastructure members)

image

and ended with this

image image

Obviously not good solution because next proxy refresh and all this is gone, so there are two problems:

  1. How to preserve interface
  2. How to avoid having manually to add interface implementation to generated ServiceClient class.

In order to solve problem #1, I have created then a folder with the same name as the proxy and drag and drop the interface to that folder. First problem solved!

In order to solve problem #2, I am utilizing the fact that the ServiceClient is generated as partial class so I create in the new folder  another partial UserServiceClient class implementing the IUserServiceClient interface. Here’s how that class look like

namespace SilverlightApplication.UserServiceProxy
{
    public partial class UserServiceClient : IUserServiceClient
    {
    }
}

I hope now you can get the reason why I was a folder with the same name as the proxy –> the namespaces of types and interfaces in that folder are matching out of the box the ones in the proxy class

And here's the solution (for visual learners like me)

image

To summarize the solution:

  • I’ve created the IServiceClient by simple extracting the facade of the proxy client interface
  • I’ve created partial UserServiceClient which is only attaching the interface to proxy
  • Both of files are  not destroyed with proxy regeneration.
  • If the WCF service contract changes over the time, regenerating of new IUserServiceClient is trivial task taking less then 15 seconds.

Duct tape solution at its best! :)

Modifying presenter

using System.Windows;
using SilverlightApplication.UserServiceProxy;
using System.Linq;

namespace SilverlightApplication
{
    public class MainPagePresenter
    {
        private FrameworkElement view;
        private IUserServiceClient userServiceClient;
        
        public MainPagePresenter(FrameworkElement view, IUserServiceClient userServiceClient)
        {
            this.view = view;
            this.userServiceClient = userServiceClient;
        }

        public void Init() 
        {
            this.userServiceClient.GetUsersCompleted += (sender, e) =>
                                       {
                                           this.view.DataContext = e.Result.Where(p => p.Salary > 1000);
                                       };
            this.userServiceClient.GetUsersAsync();
        }
    }
}

As you can tell I’ve made two changes:

  • added another parameter to the constructor injecting the newly created IUserServiceClient interface
  • Modified Init method to replace proxy instantiation with usage of injected client proxy abstraction.

Modifying the view

Usually I wouldn’t modify the view but instead rely on IoC container to inject the UserServiceClient instance, but in order to keep this post focused I won’t be using IoC here (you’ll see it in one of my future posts showing my Prism enhancements) so I needed to make a simple change in a page constructor

        public MainPage()
        {
            InitializeComponent();
            this.presenter = new MainPagePresenter(this, new UserServiceClient());
            this.Loaded += new RoutedEventHandler(MainPage_Loaded);
        }

Nothing special, just added new UserServiceClient() to the parameters being passed to a presenter.

Running the app again

image

Yeap, still works :)

Where’s the unit test?

Well, this blog post is long enough (and it is late enough :)) so I would skip the unit test example this time because it is fairly trivial to be written now when we have interface of the service proxy.

Summary

In this blog post I showed another way how to easy introduce a layer of simple abstraction between the WCF service proxy and the code consuming it.

I find the advantage of my approach VS the two of others in its simplicity and maintainability but again considering I “invented it” that comes as no surprise to me :)

Source code of the end solution can be downloaded from here.

del.icio.us Tags: ,,,
Comments (6) Trackbacks (0)
  1. Excellent post, thanks a lot. One thing I found interesting though was that I wrote something similar around WCF and MVVM not long ago and found that WCF proxy had a pregenerated interface already on it.

    What's strange is that was almost exactly the same as your service. Some tooling difference? Woud love to know your opinion

  2. Nigel,

    I was doing this "more then a few times" in both VS2008 and VS2010 with Silverlight, Wpf and ASP .NEt and never seen  that IUserServiceClient  interface

    What I have seen is |IUserService| (being a service contract) but in Silverlight async scenarios (and WPF if you want to have easy multy targeting scenario) that result with that interface having pairs BeginXXX and EndXxx etc -> totally different API then the one from client I am using in my post

    Can you please post a link to your blog post where you presented your case? I am dying to see that

  3. I've been back and double checked it (running Visual Studio 2008 with Silverlight 3) and Reference.cs contained two interfaces ICocktailService and ICoctailServiceChannel. Haven't used the latter, but the former contained the BeginX and EndX method pairs (but not the events exposed by the actual implementation CocktailServiceClient).

    The post is at compiledexperience.com/…/Blendable-MVVM-WCF-and-Asynch-Data-Sources but I didn't put the generated interface in (didn't think it was overly special), but had a few emails about it not being generated for others so I'm looking into why.

    It's really strange, initially thought it was because both server and client were in same solution, but tried from a seperate solution to get the interface.

    Will comment here when I have some definate answers (I've just checked and my work computer is generating interfaces as well).

    Could it be .net 3.5 SP1?

  4. Hey again, been trying pretty hard to generate a proxy that didn't contain an interface with no luck.

    Did find this page msdn.microsoft.com/…/ms733133.aspx which shows the output of svcutil which includes the two interfaces.

    Not sure why you (and a few of my readers) aren't getting that interface. If you do find out can you let me know at nigel.sampson@compiledexperience.com

  5. It is probablly related to the fact that "we" don’t have in our code service contract as separate interface but instead implementation class gets decorated by attributes.

    If you look at Reference.cs in my sample you would find UserService interface (note NOT IUserService)

       public interface UserService {

           System.IAsyncResult BeginGetUsers(AsyncCallback callback, object asyncState);

           ObservableCollection<User> EndGetUsers(IAsyncResult result);

       }

    The main difference between our two approaches is that your comes out of box but requires one to use the BeginXXX, EndXXX syntax while mine requires some work but allows using xxxAsync + xxxCompleted event handler.

    IMHO, "the more the merrier" so it is good we came out with two different approaches :)

  6. Ahhh, now it makes a lot more sense.

    Thanks for that


Leave a comment

No trackbacks yet.