Developing on Staxmanade

WCF Service Proxy inside Silverlight with a generic type

We've implemented a silverlight 2 business application communicating through WCF and I just had to blog about something I found possible in .net in general...

On the server side we have a very simple generic object used to communicate validation issues back to our Silverlight client when a web service method is called. Here's the basic interface.

public interface IValidatedResult<T>
{
  T Result { get; set; }
  List<string> ValidationIssues { get; set; }
}

Now if you had a method that exposed this generic result object through your web service...

public ValidatedResult<long> StringLength(string param1)
{
  return new ValidatedResult<long>(param1.Length);
}

Now if you to to the silverlight project tell Visual Studio to generate a proxy for you (against the service you just created) it will give you a proxy with an object that is not generic. You end up with some autogenerated code that looks more like...

public partial class ValidatedResultOflong : object, System.ComponentModel.INotifyPropertyChanged
{

  private long ResultField;

  private System.Collections.ObjectModel.ObservableCollection<string> ValidationIssuesField;

  [System.Runtime.Serialization.DataMemberAttribute()]
  public long Result
  {
    get
    {
      return this.ResultField;
    }
    set
    {
      if ((this.ResultField.Equals(value) != true))
      {
        this.ResultField = value;
        this.RaisePropertyChanged("Result");
      }
    }
  }

  [System.Runtime.Serialization.DataMemberAttribute()]
  public System.Collections.ObjectModel.ObservableCollection<string> ValidationIssues
  {
    get
    {
      return this.ValidationIssuesField;
    }
    set
    {
      if ((object.ReferenceEquals(this.ValidationIssuesField, value) != true))
      {
        this.ValidationIssuesField = value;
        this.RaisePropertyChanged("ValidationIssues");
      }
    }
  }

  // stripped out the INotifyPropertyChanged goo
}

Notice the non generic type ValidatedResultOflong that was generated? This non generic object is great and all except when you want to do some generic processing on these objects. For things like error handling, validation handling... if we had to create different handling methods for all of these different objects, that could prove to be laborious...

Say I wanted to write an extension method to do some generic processing on all objects that are a ValidatedResult of T... Unfortunately there is no common signature we can key off of to write this method with the proxy code generated by V.S.

Then I thought I would try something... Can you have a partial class in one area which contains a common property, in this case each contains a "Result" and a "ValidationIssues" property and another partial class in a different location that declares it implements an interface which defines that "Result" and "ValidationIssues" property... and would that compile?

So I wrote my first test...

Here is our auto generated partial class simulated...

public partial class Foo
{
  public bool Result { get; set; }
}

I then wrote a generic result of T to define the object has a Result property.

public interface IResult<T>
{
  T Result { get; set; }
}

And now the specific implementation with a long Result type.

public partial class Foo : IResult<long> {}

After putting those three structures together I hit Build in VS and to my surprise (at first, but now it makes total sense) it compiled... This was great news. This meant I could create a generic processor for my wcf objects in silverlight... I'll show how on the silverlight side below...

I defined the validated result contract as follows...

public interface IResultProperty<T>
{
  T Result { get; }
}

public interface IValidatedResult<T> : IResultProperty<T>
{
  List<string> ValidationIssues { get; set; }
}

This meant I could quickly create partial class stubs for each of the wcf generated objects that looked like... ValidatedResultOf{object} and would define to the compiler that all these objects truly implemented the ValidationIssues and Result property.

Here's an example of the partial class for the ValidatedResultOflong

public partial class ValidatedResultOflong : IValidatedResult<long> { }

With that in place, this meant I could create some generic handling methods for all of my objects that now implement IValidatedResult<T>...

public static bool HasValidationIssues<T>(this T validatedResult)
where T : IValidatedResult<T>
{
  if (validatedResult != null &amp;&amp;
  validatedResult.ValidationIssues != null &amp;&amp;
  validatedResult.ValidationIssues.Count > 0)
  return true;
  else
  return false;
}

Don't know if i've very heard anyone talk about one partial class containing some property or common method and being able to create another partial class that defines the interface contract for that... Pretty cool...

Comments

Jason.Jarrett
Interesting observation. Thanks for sharing.

I haven't pushed it very far (bool, string, MyCustomObject, etc)

Boris Modylevsky
Thanks for the post. It's really exciting to receive a proxy of Generic class. It really works smoothly with "simple" classes. But more complex ones result with random names in Silverlight proxy. For example, my `_SimpleTree_` became _SimpleTreeNodeOfItemErNMAaNV_
Jason.Jarrett
Ok, I quickly threw an example together. I didn't comment much, but the code's there and "works on my box..."
Let me know if you have any troubles either understanding it, or getting it working.

I've never used this file host service, but giving it a try... I've placed the project here [ http://www.filesavr.com/validatedresultsample](http://www.filesavr.com/validatedresultsample)

Also the only concepts to really look at here are the `ValidatedResult<T>`` and the notion of the partial classes used along side the VS service reference code to get the extension methods to work... This by no means follows best practices with some of this stuff.

Good luck!</div>
greg
... very much appreciated!!
Jason.Jarrett
Greg,
I will try to put together an example and post it here soon.</div>
greg
... too many snippets for me to get the big picture... It looks promising, though. Do you have a simple working example you could post? I am interested in the generic proxy concept whether used within Silverlight or otherwise. Thanks in advance.