Building refactoring-friendly observable objects in C#


INotifyPropertyChanged is one the most frequently used .NET interfaces nowadays. I use this interface every day within the models in all kinds of applications: Windows Forms, WPF, Silverlight.

However there is one disadvantage in using INotifyPropertyChanged I have to deal with very often – it is not “refactoring-friendly” and requires a lot of efforts when supporting large scalable enterprise applications/frameworks.

Here’s a skeleton of a common observable object exposing INotifyPropertyChanged interface we all usually deal with:

public class MyCommonObject : INotifyPropertyChanged
{
  #region INotifyPropertyChanged Members

  public event PropertyChangedEventHandler PropertyChanged;

  protected void OnPropertyChanged(string propertyName)
  {
    var handler = PropertyChanged;
    if (handler != null) 
      handler(this, new PropertyChangedEventArgs(propertyName));
  }

  #endregion
}

 

Now let’s take a “Name” property that supports value change notifications:

public class MyCommonObject : INotifyPropertyChanged
{
  private string _Name;

  public string Name
  {
    get { return _Name; }
    set
    {
      if (_Name == value) return;
      _Name = value;
      OnPropertyChanged("Name");
    }
  }

  #region INotifyPropertyChanged Members  
  #endregion
}

 

When you want to rename “Name” property above to something like “FirstName” using some refactoring tool the notification will work properly only when the “OnPropertyChanged” call argument is changed as well. It is quite easy to change the code above to call OnPropertyChanged(“FirstName”) but it’s not so easy when you deal with hundreds of objects with possibly hundreds of properties spread over more than one project/solution. Sometimes it is not only the property who notifies about value changes and this makes the refactoring/support task extremely difficult and error-prone.

Being tired of searching broken “OnPropertyChanged” occurrences I’ve started to think over modifying this pattern in order to make it “refactoring-aware”. I wanted to pass something like a “pointer” to the property rather than it’s name so that each time the property name is changed the “pointer” does not require additional tuning. After trying out several approaches I finally found the one that perfectly suits my needs.

Linq Expressions to the rescue…

I’ve decided to reuse Linq Expressions and lambda Functions in order to pass a strongly-typed reference to the object’s property for the “OnPropertyChanged” method. I ended with the following modification of basic “INotifyPropertyChanged” implementation:

public class ObservableObject<T> : INotifyPropertyChanged
{
  public event PropertyChangedEventHandler PropertyChanged;

  protected virtual void OnPropertyChanged(Expression<Func<T, object>> property)
  {
    if (property == null || property.Body == null) return;

    var memberExp = property.Body as MemberExpression;
    if (memberExp == null) return;
    
    var handler = PropertyChanged;
    if (handler != null)
      handler(this, new PropertyChangedEventArgs(memberExp.Member.Name));
  }

As you can see “OnPropertyChanged” method was changed to receive Expression<Func<T, object>> instead of a string-based property name.

You don’t need compiling or executing this expression. The primary goal is accessing its Body that is represented by a MemberExpression. MemberExpression instance wraps a common “System.Reflection.MemberInfo” as a Member property and so it is obvious that you can get the actual name of the property based on reflection and create a proper event arguments on the fly.

Note: This is a basic implementation and does not consider various possible scenarios. I simply exit method execution if things go the unexpected way. You may want providing some exceptions or error handling.

As you may have noticed I’ve provided a generic class implementation that can be consumed by my objects. Here’s a basic sample of the object consuming modified pattern:

public class MyObject : ObservableObject<MyObject>
{
  private bool _BoolProperty;
  public bool BoolProperty
  {
    get { return _BoolProperty; }
    set
    {
      if (_BoolProperty == value) return;
      _BoolProperty = value;
      OnPropertyChanged(@this => @this.BoolProperty);
    }
  }

  private int _IntProperty;
  public int IntProperty
  {
    get { return _IntProperty; }
    set
    {
      if (_IntProperty == value) return;
      _IntProperty = value;
      OnPropertyChanged(@this => @this.IntProperty);
    }
  }

  private string _StringProperty;
  public string StringProperty
  {
    get { return _StringProperty; }
    set
    {
      if (_StringProperty == value) return;
      _StringProperty = value;
      OnPropertyChanged(@this => @this.StringProperty);
    }
  }

  private object _ObjectProperty;
  public object ObjectProperty
  {
    get { return _ObjectProperty; }
    set
    {
      if (_ObjectProperty == value) return;
      _ObjectProperty = value;
      OnPropertyChanged(@this => @this.ObjectProperty);
    }
  }
}

 

I guess the sample above does not need detailed comments. Instead of string-based property name you now pass the property. If you or someone else decides refactoring the name of the property all notification logic will be automatically updated.

Proper implementation

However when running the following test I found that the code above was not working as expected:

class Program
{
  static void Main(string[] args)
  {
    MyObject my = new MyObject();
    my.PropertyChanged += (sender, e) => Console.WriteLine(e.PropertyName);

    my.BoolProperty = true;
    my.IntProperty = 100;
    my.StringProperty = "something";
    my.ObjectProperty = 100;

    Console.WriteLine("Press Enter to exit...");
    Console.ReadLine();
  }
}

I was receiving only notifications for “StringProperty” and “ObjectProperty” properties, but nothing for “BoolProperty” and “IntProperty”.

After some investigation I found out that my problem was in “object” declaration in Expression<Func<T,object>>. Linq wraps value type instances with additional “Convert” expression so my check for “MemberExpression” was receiving null value during type casting.

This produced another slight modification that covered all aspects of expression passing:

public class ObservableObject<T> : INotifyPropertyChanged
{
  public event PropertyChangedEventHandler PropertyChanged;

  protected virtual void OnPropertyChanged(Expression<Func<T, object>> property)
  {
    if (property == null || property.Body == null) return;

    var memberExp = property.Body as MemberExpression;
    if (memberExp == null)
    {
      UnaryExpression unary = property.Body as UnaryExpression;
      if (unary != null) memberExp = unary.Operand as MemberExpression;
      if (memberExp == null) return;
    }

    var handler = PropertyChanged;
    if (handler != null)
      handler(this, new PropertyChangedEventArgs(memberExp.Member.Name));
  }
}

As you can see I’ve added a fallback step to check whether an Unary Expression is actually being received. In this case I’m taking it’s Operand as the expected Member expression and this works like magic. Now my test output is correct and provides notification for all the properties.

Notes

The approach above consumes more CPU cycles than the common INotifyPropertyChanged use so it might slightly decrease performance. However I’m sure it may greatly reduce the cost of code support in future and save your time and money.

Feel free playing with the source code for this article.

Windows Automation: Automating Windows 7 Notepad within S# Script


Today we have updated S# with another sample covering the use of Windows Automation API from within a common S# script.

Auto# (AutoSharp)

This is a demo project shows how easily your S# scripts can be enhanced with a set of functions that target Windows UI Automation API and the ways of forming a QA-friendly language on the top of S# runtime. Full source code for this sample is available within the latest S# runtime update here.

Note: Sample project targets Windows 7 Notepad and may not work properly on other versions of Windows because of control ids difference.

To find Windows Automation API for your version of Windows please refer to this article.

Auto# introduces 9 functions that provide Windows Automation support S# scripts:

  • Kill – close all running instances of some process
  • Launch – launch a new process and return its main window
  • Wait – sleep for some time, often required when waiting application response
  • FindByClassName – finds element by Class Name
  • FindById – finds element by Automation ID
  • FindByName – finds element by its Name
  • Expand – expands menu element
  • InvokeById – invokes element by Automation ID
  • FocusEditor – focuses textbox editor

The following workflow is executed in order to automate Notepad:

  1. Kill all running Notepad instances
  2. Launch a new Notepad process
  3. Type some text
  4. Click “File” – “Save As” in the main menu
  5. Type destination file name
  6. Agree to overwrite existing file if confirmation dialog appears
  7. Click “File” – “Exit” to close Notepad

Here’s how the S# script may look like:

// Close existing instances of Notepad

Kill(“notepad”);

 

// Launch a new Notepad instance and get main window

window = Launch(“notepad”);

// Wait 1 second

Wait(1000);

 

// Get main editor region

edit = FindByClassName(window, “Edit”);

 

// focus main editor

FocusEditor(edit);

 

// Send sample text to the editor region

SendKeys.SendWait(“Automating Notepad using Windows UI Automation and S#”);

Wait(3000);

 

// Find [File] menu

mnuFile = FindById(window, “Item 1″);

 

// Expand [File] menu

Expand(mnuFile);

Wait(1000);

 

// Invoke [Save As] menu item

InvokeById(window, “Item 4″);

Wait(1000);

 

// Get [Save As] dialog

saveAsDialog = FindByName(window, “Save As”);

 

// Get access to [FileName] textbox

saveAsName = FindById(saveAsDialog, “1001″);

 

// Focus filename editor

FocusEditor(saveAsName);

 

// Write down file name

SendKeys.SendWait(“D:\\MyTextFile”);

// Send [Enter] keypress

SendKeys.SendWait(“{ENTER}”);

Wait(1000);

 

// Check whether Overwrite Dialog appeared

confirmSaveAs = FindByName(saveAsDialog, “Confirm Save As”);

if (confirmSaveAs != null)

{

    // Click [OK] button

    InvokeById(confirmSaveAs, “CommandButton_6″);

    Wait(1000);

}

 

// Expand [File] menu

Expand(mnuFile);

Wait(1000);

 

// Click [Exit] item

InvokeById(window, “Item 7″);

 

 

Demo project also includes a very simply UI providing possibility to alter the script above and execute it.

Unleash your fantasy :)

S# 1.1 and Processing# Visualization Language for Silverlight 3.0


We are happy to announce that S# 1.1 was released today.

“Extension Methods”

It is now possible extending .NET types with custom methods that can be invoked during script execution. It is not the support for.NET extension methods but functionality is somewhat similar.

Let’s take a .NET “System.Math” class. It is a static class that “Provides constants and static methods for trigonometric, logarithmic, and other common mathematical functions”. You can freely access all its members from S# script (omitting namespace) but at some point you may want to extend existing set of methods with some custom or missing (in your opinion) ones. For example conversion to radians, mapping/constraint of numeric values, distance calculation, etc. But “System.Math” is a static class and cannot be inherited for customization purpose.

In S# 1.0 we used the following workaround for such cases: we would have created a “MathEx” class to mimic “System.Math” one with same methods being re-directed to original “Math” plus containing additional members like “Distance()”, “Radians()” etc. After that we’ve been suppressing original “Math” class with our own implementation with the help of RuntimeHost features like “AddType”: RuntimeHost.AddType(“Math”, typeof(MathEx)); From that moment all “Math.*” calls were redirected to a custom implementation and original “System.Math” was hidden from the scripts.

Though the approach above is still valid and you can easily suppress any type with your own implementation we decided to provide an out-of-box support in S# 1.1 for such scenarios:


RuntimeHost.TypeManager

.AddExtensionMethod(typeof(Math), “Constrain”, new
MathExtensions.Constrain())

.AddExtensionMethod(typeof(Math), “Degrees”, new
MathExtensions.Degrees())

.AddExtensionMethod(typeof(Math), “Distance”, new
MathExtensions.Distance())

.AddExtensionMethod(typeof(Math), “Distance2D”, new
MathExtensions.Distance2D())

.AddExtensionMethod(typeof(Math), “Distance3D”, new
MathExtensions.Distance3D())

.AddExtensionMethod(typeof(Math), “Map”, new
MathExtensions.Map())

.AddExtensionMethod(typeof(Math), “Radians”, new
MathExtensions.Radians());

Now you can create invokable functions and bind them to ANY .net type with a single line of code. The sample above demonstrates how easily “System.Math” type is enriched with 7 new methods. Here’s how I’m using it now within my scripts:

ang1 = Math.Radians(i); // convert degrees to radians

ang2 = Math.Radians(j); // convert degrees to radians

pos1 = Surface.Width/2 + (sc * Math.Cos(ang1));

pos2 = Surface.Width/2 + (sc * Math.Sin(ang1));

pos3 = Surface.Width/2 + (sc * Math.Cos(ang2));

pos4 = Surface.Width/2 + (sc * Math.Sin(ang2));

We hope this feature will greatly reduce development efforts for numerous scenarios as well as well as enrich your scripts.

Processing# Visualization Language for Silverlight 3.0

“Processing#” is a showcase sample demonstrating most of the powerful capabilities of S#. Being greatly inspired by “Processing” language implementation in Java we decided to port it to Silverlight powering with S# runtime. After installing S# 1.1 runtime you will find the complete source code under the “Samples\Silverlight 3.0″ folder.

Solution contains a simple console where you can write and immediately execute scripts. There are more than 30 “Processing.org” samples that were successfully ported to “Processing#” and that are available within the Silverlight console. The syntax was made slightly different by intention and will be getting more parity in later versions.

Source code also contains a ported to Silverlight demo from “OpenProcessing.org” to demonstrate the capabilities of Processing# powered by S# 1.1 runtime:

function Setup()

{

 

Surface.Size(320, 480);

 

//Main Body

Surface.Defaults.StrokeThickness = 2;

Surface.Defaults.Fill = new SolidColorBrush(Color.FromArgb(255, 203, 224, 142));

 

using (Surface)

{

    BeginShape();

    Vertex(154, 65);

    Vertex(182, 71);

    Vertex(225, 82);

    Vertex(250, 90);

    Vertex(258, 96);


The image above is rendered by Silverlight 3 and has no visual difference comparing to that created by Java.

You can download the latest runtime with Processing# demo here: Orbifold S# Runtime 1.1

Introducing S# scripting language and runtime


Today we are very excited and proud to announce that we finished testing and moved to the packaging procedure for our next brainchild called “Orbifold S#“. The purpose of this article is to give a brief overview of what S# actually is, key features and possible use cases.

S# is a weakly-typed dynamic language and runtime infrastructure to make your applications extendable, customizable and highly flexible. It allows introducing expressions and large code blocks evaluation within your applications in the similar way Microsoft Office deals with VBScript, gives you possibilities providing rich formula evaluation capabilities like it can be seen in MS Excel, etc.

“Orbifold S# Runtime” will be distributed absolutely free for academic and non-commercial usage!. You can download runtime right now from here.

The key principles of S# are:

  • Be simple
  • Be efficient
  • Be intuitive

S# runtime has been designed to be easily hosted by applications. Minimum script execution scenario requires two lines of code! The important part of S# is its well-defined extendable runtime engine together with the application programming interface that allows full bi-directional communication between script and application code. In particular it is easy to extend S# by embedding external functions and functional objects, shared static or dynamic variables, operator handlings and type filters from the host application. Moreover the execution semantics of some language constructs has extensibility mechanisms available externally. This enables developers to create user-friendly executable business/domain specific languages on S# basis.

S# can work in single-expression mode in order to execute string expressions to values. This is especially helpful when application should allow users executing only light-weight portions of the functionality. S# is a pure .NET interpreted language completely written in C#.

For the moment it is ported to the following platforms:

  • Microsoft .NET 3.5 (SP1)
  • Microsoft Silverlight 3.0
  • Microsoft .NET Compact Framework
  • Microsoft XNA Framework
  • MONO

This means that S# runtime can be hosted by applications based on .NET like Console, Windows Forms, ASP.NET, Silverlight 2 and 3, Windows Presentation Foundation (WPF), XNA (both PC and XBox scenarios) and MONO (Linux).

Key features that will be dwelled on in the upcoming articles are:

  • Designed to be easily embedded into applications
  • Highly extensible grammar and language
  • Rich and controlled communication between runtime and host application in both directions
  • Sits on the top of .NET, has support for interaction with .NET code
  • Works in a single-expression evaluation mode to execute string expressions to values and return results to application
  • No code emitting, no CodeDom or background compilation, 100% interpreted language (own Virtual Machine and Debugging facilities are in progress)
  • Completely in-memory execution, does not require temp files, local system access, etc
  • C# and Java-like language syntax designed to be familiar to .NET and Java developers; easy to study for non-developer users
  • Various platforms are supported
  • Fully remotable; expressions and scripts can be sent across the wire and executed on a remote machine
  • Weakly-typed as IronPython and IronRuby for .NET

Installation Experience

You will need a couple of clicks in order to install S# runtime on your machine. For the moment runtime requires less than 1 MB on you hard drive.

SSharp_Installation_1

SSharp_Installation_2

SSharp_Installation_3

SSharp_Installation_4

For the moment you will have runtimes only for .NET 3.5 and Silverlight 3.0 installed by default. Both components are automatically registered within the “Add Reference” dialog in Visual Studio 2008 (note this requires installation to be started by a user with administrator account).

When creating a new Silverlight application you will be able adding S# reference without any additional implications related to finding the assembly installed on the local drive:

SSharp_Installation_VS

From Installation right to Execution

I am going to show you how easily you can start hosting S# runtime right after installation process is finished. You need to create an empty “Silverlight 3″ application project and add reference to “Orbifold S# for Silverlight” assembly using “Add Reference” dialog in Visual Studio 2008.

Next open “MainPage.xam” file and add a Canvas control. We are going to execute scripts that perform some operations against the Canvas element.

SSharp_Intro_1

After that you will need opening the code-behind file “MainPage.xaml.cs”. S# runtime hosting will require at least 2 namespaces involved: “Orbifold.SSharp” and “Orbifold.SSharp.Runtime”

SSharp_Intro_2

Note that S# runtime should be initialized before executing scripts. This procedure should be done once and I would recommend placing “RuntimeHost.Initialize()” method call somewhere in “App.xaml.cs” in the future.

Now it’s time to do some scripting on the “MainPage.Loaded” event:

SSharp_Intro_3

S# runtime supports a large amount of Scoping facilities (local scopes, global scopes, dynamic or application-controlled scopes). The same goes to execution contexts. Execution Contexts is a highly valuable and extensible area that deserves a separate article. All this will be  described in future articles and in API guides.

As I want promoting my “canvas” element to the runtime I need creating a simple execution context for my future script and provide possibility accessing “canvas” during runtime. This is achieved by adding a “canvas” variable to the scope that references our “canvas” element inside application. Note that you can provide any “alias” you want and it may not carry the same name as host-side variable/element.

Next step is defining the body of the script. I’m going to assign a new background brush for the Canvas and add a Rectangle element. Note that I don’t have to use full namespace paths for .NET classes as they are resolved automatically by S# runtime. You may forget about endless “using” clauses here.

After that I create a Rectanlge, configure it’s properties (including attached ones) and add it to the Children collection of the Canvas control by referencing “canvas” variable.

Finally I call “Script.RunCode” providing the body of the script and root execution context. When launching this Silverlight application you will see the following result:

SSharp_Intro_4

Yes, everything works perfect. Script got access to application structures and even managed to create and add new objects using core .NET Silverlight functionality. I would like to highlight “namespace resolving” feature once more as it really simplifies coding efforts. Let’s extend the script above to apply rotation for the Rectangle shape. “RotateTransform” class resides in “System.Windows.Media” namespace in Silverlight 3.0.

SSharp_Intro_5

As S# is a weakly-typed language you don’t have a need worrying about value types as they will be resolved automatically during runtime.

When running modified script you should see the following results:

SSharp_Intro_6

Extending Language with Custom Functions

Though S# supports a huge part of C# syntax constructions it may be required adding some domain-specific constructions or functions that simplify script building for end-users.

I am going to create two new functions: “CreateRectangle” that creates a Rectangle shape in a simplified manner and “Rotate” that will rotate FrameworkElement.

CreateRectangleFunction

SSharp_Ext_2

RotateElementFunction

SSharp_Ext_3

Both functions are fairly simple and don’t require comments. Please note that each S# function element should expose “IInvokable” interface. This is the only requirement for external functions integration.

In order to promote these functions you will need to include them into the scope the same fashion “Canvas” element was done – ScriptContext.SetItem() method. However to reduce development time there are also generics-based methods:

SSharp_Ext_1

Note that you can provide any name for the function. In this case I used “CreateRectangle” and “Rotate”. Now let’s modify the code from the samples above in order to consume new functions:

SSharp_Ext_4

This time the code becomes less complex but more efficient. I can create a Rectangle shape providing position and size and can call “Rotate” in order to apply Rotate Transformation.

Just for demonstration purposes I’ve added a function usage sample. I’ve introduced a function (event handler) called “OnCanvasClick” that is wired with “MouseLeftButtonDown” event of Canvas. Function requests access to global variable scope via the “global” keyword (similar to PHP)

SSharp_Ext_5

Now if you execute a script Rectangle will rotate 10 degrees each time you click design surface with a left button of the mouse. Another important point is that weakly-typed and dynamic nature of S# allows me accessing Angle value of RenderTransform property as of RotateTransform actually. By default RenderTransform property is of Transform type. S# didn’t require me doing type casting or conversion in order to set property value and this is really helpful in many scenarios.

The S# language has a great number of features and runtime is extremely extensible. We will unveil more details, links and samples for S# very soon.

UPDATE: Meanwhile we are finishing all the packaging work you can download the raw runtime (without documentation, samples and some other stuff) right now here.

Silverlight 3 PropertyGrid Development Progress


There was no information about Silverlight version of the PropertyGrid control for some period. I would like to leak some information towards the current development progress as well as highlight some of the most remarkable features.

Multiple layouts support

Silverlight PropertyGrid will support at least Alphabetical and Categorized layouts out-of-box. There will be a possibility to write your own layouts with least amount of efforts possible.

Here’s how the the “Categorized” one looks like and defined in XAML:

SPG01

SPG02

“Categorized” layout will be the default one. This means that you won’t need defining anything if “Categorized” behavior is those you expect to have by default.

Note that control will support “Description Box” similar to native Windows Forms PropertyGrid control.

Here’s how the “Alphabetical” layout looks like and defined in XAML:

SPG03

SPG04

Both POCO (Plain Old CLR Objects) and Dependency objects are to be supported. Here’s the Button control bound to PropertyGrid:

SPG05

Property Filtering feature will provide exactly the same functionality Microsoft Expression Blend’s PropertyGrid control gives. It will be possible to filter out properties according to their names and types:

SPG06

SPG07

After Silverlight 3 went RTM the Silverlight PropertyGrid development progress went rapid and smooth and hopefully the control will be available very soon.

More news are coming soon…

Reflection Limitation in .NET 3.5/4.0


Recently a colleague of mine pointed to a strange behavior in .NET Reflection  that pushed me doing a lot of additional investigations and finding out a very serious limitation that might raise a lot of issues if not being taken into account.

When you declare property as “virtual” beware that custom attributes won’t be fetched for the derived one if the property is being overrided.

This can be easily tested. First you need creating two custom attributes that will target two cases: virtual property and virtual method.

  [AttributeUsage(AttributeTargets.Property, AllowMultiple = false, Inherited = true)]
  public class MyPropertyAttribute : Attribute
  {
  }

  [AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
  public class MyMethodAttribute : Attribute
  {
  }

Now you can create two classes: “BaseClass” that will contain a single virtual property and single virtual method and “DerivedClass” that will override both members.

 public class BaseClass
  {
    private string _PropertyVirtual;

    [MyProperty]
    public virtual string PropertyVirtual
    {
      get { return _PropertyVirtual; }
      set { _PropertyVirtual = value; }
    }

    [MyMethod]
    public virtual void MethodVirtual()
    {
    }
  }

  public class DerivedClass : BaseClass
  {
    public override string PropertyVirtual
    {
      get { return base.PropertyVirtual; }
      set { base.PropertyVirtual = value; }
    }

    public override void MethodVirtual()
    {
      base.MethodVirtual();
    }
  }

The problem starts when you try fetching custom attributes for “PropertyVirtual” from within a DerivedClass because you will never get them using PropertyInfo.GetCustomAttributes method call. Here’s a sample Console Application to ensure the limitation is alive:

  class Program
  {
    static void Main(string[] args)
    {
      Console.WriteLine("Checking virtual property attributes:\r\n");

      Console.WriteLine(
        "BaseClass.PropertyVirtual attributes count: {0}",
        typeof(BaseClass).GetProperty("PropertyVirtual").GetCustomAttributes(true).Length);

      Console.WriteLine(
        "DerivedClass.PropertyVirtual attributes count: {0}",
        typeof(DerivedClass).GetProperty("PropertyVirtual").GetCustomAttributes(true).Length);

      Console.WriteLine("\r\nChecking virtual method attributes:\r\n");

      Console.WriteLine(
        "BaseClass.MethodVirtual attributes count: {0}",
        typeof(BaseClass).GetMethod("MethodVirtual").GetCustomAttributes(true).Length);

      Console.WriteLine(
        "DerivedClass.MethodVirtual attributes count: {0}",
        typeof(DerivedClass).GetMethod("MethodVirtual").GetCustomAttributes(true).Length);

      Console.ReadLine();
    }

Upon running this sample you should see the following results:


Checking virtual property attributes:

BaseClass.PropertyVirtual attributes count: 1
DerivedClass.PropertyVirtual attributes count: 0

Checking virtual method attributes:

BaseClass.MethodVirtual attributes count: 1
DerivedClass.MethodVirtual attributes cound: 1

As you can ensure there are no custom attributes returned for overrided virtual property while the expected result is fetched for overrided virtual method.

You can easily find what is happening under the hood if switching to MSIL representation of the classes coded above. Here’s how the “BaseClass” attribute usage looks like:

Reflection Issue 1

As you can see on the IL level “MethodVirtual” declares “MyMethodAttribute” instance right within its own body. The same goes for “PropertyVirtual” – a getter, a setter and attribute declaration.

However both members look like the following when derived:

Reflection Issue 2

While “MethodVirtual” still refers to “base.MethodVirtual” and theoretically can invoke attribute declaration,

note that the following overriding will still work for methods:

  public class DerivedClass : BaseClass
  {
    public override string PropertyVirtual
    {
      get { return base.PropertyVirtual; }
      set { base.PropertyVirtual = value; }
    }

    public override void MethodVirtual()
    {
      //base.MethodVirtual();
    }
  }

“PropertyVirtual” is no longer related to a base implementation. We have a completely new property definition that is wired with base getter and setter. But no custom attribute declaration!

This means that the default code written for MemberInfo class won’t be able fetching anything except empty object array.

There are two workarounds I found that help switching to another MS developer(s) work, custom attribute fetching seems to be completely different in the following approaches: TypeDescriptor and old-fashioned Attribute class.

      Console.WriteLine(
        "DerivedClass.PropertyVirtual attributes count: {0}",
        Attribute.GetCustomAttributes(typeof(DerivedClass).GetProperty("PropertyVirtual"), typeof(MyPropertyAttribute)).Length);

The code above will be able to fetch and display custom attributes for a virtual property. Same can be achieved by means of property descriptors:

      Console.WriteLine(
        "DerivedClass.PropertyVirtual attributes count: {0}",
        TypeDescriptor.GetProperties(typeof(DerivedClass))["PropertyVirtual"].Attributes[typeof(MyPropertyAttribute)] != null);

However the last one will have a great performance overhead in comparison with the “Attribute.GetCustomAttributes” usage.

I’ve tested the same issue with .NET 4.0 (beta 2) and it is still there. I really hope this article will help you detecting problems with your software and eliminating issues related to this very case.

You can find the source code for this article here: MetadataIssue

WPF PropertyGrid: Telerik WPF Controls 2009 Integration Kit


I’m glad to announce that we are going to include a “Telerik WPF Controls 2009” Integration Kit into every “Orbifold WPF PropertyGrid 2.0″ package. This is a quick start WPF project demonstrating how easily Telerik Controls 2009 can be used for property editing within the Orbifold PropertyGrid control. Getting started guide will also be upgraded to cover Telerik integration steps.

WPG 2.0 Fully Functional Demo

It should take less than an hour to reproduce the given project. The screenshots are given below.

Color Picker

WPG_Color_01

WPG_Color_02

Date and Time Pickers

WPG_DateTime_01

WPG_DateTime_02

WPG_DateTIme_03

Masked Editors (Date and Time)

WPG_Masked_01

Masked Editors (General)

WPG_Masked_02

Numeric Editors

WPG_Numeric_01

Hope you will enjoy this kit.

First WPF Parallel Coordinates Control


I’m glad to announce that together with Francois Vanderseypen we’ve successfully introduced the first WPF Parallel Coordinates Control for a customer of ours! At least I could not find any one in the Google for the moment of writing this article ;)

“ParaGraph” is capable of displaying any types of data like strings, doubles, datetimes, etc. and can be easily bound to a DataTable instance. It has no problems visualizing CSV/Spreadsheet data bound to it. The control it is highly customizable and nearly every visual feature can be switched off/on as well as configured either via xaml and control templates or code behind settings.

The Demo Application demonstrating basic functionality can be found here

1. Overall look of the demo application:

 

image1-overall-look1

2. Support for Background Grid and Range labels:

image2-background-grid-and-range-labels3

3. Lines Highlighting and Tooltips

image3-line-highlighting-and-tooltips1

4. Histogram (Emphasizing the Accumulation Points)

image4-histogram1

5. Axes scaling (zooming in and out)

image5-axes-scaling1

By default control resides in “Swap” mode. You can drag each single Axis to a different location in order to change (swap) them immediately with redrawing of all corresponding data values. 

6. Line Thickness/Hover Thickness

image6-line-and-hover-thickness1

These are the key features I wanted to highlight but not the all amount ;)

For more details please refer also to the initial announcement here.

Immediate Window. Generating and executing lambdas across application domains.


First I’d like to say thank you words to Igor Moochnick. His article CodeDom extensions and dynamic LINQ (string/script to LINQ emitting) gave me a lot of pleasure extending it a bit and creating shorter code in a Linq manner flow. Refer to his article for more details on CodeDom and extension methods he introduced.

Introduction

Due to some purposes I needed creating a quick implementation of some kind of "Immediate Window" that could allow me executing methods and setting properties for object instances at live running application. I tried several approaches. Among them were "Dynamic Methods", extending "Linq Dynamic API" and parsing commands and property paths to be able using them against reflection. But at last moved to code generation as the most easiest and quickest way of accomplishing the task.

Imagine you have a small TextBox based pad in the running WPF application similar to "Immediate Window" pad in Visual Studio and you are willing to execute the following snippet against the main application window:

this.Title = "NewTitle"

(this.FindName("btnExecute") as Button).SetValue(Button.ContentProperty, "NewContent")

(this.FindName("stackPanel") as StackPanel).Children.Add(new Button() { Content="xxx" })

So these lines should be transformed into the code from their string representation and executed in runtime against the running Window as the code is supposed to perform some actions against the Window instance.

What I’ve decided to do was similar to the following ideas:

1. We should have the dynamically generated method that will have our text line as it’s body (though with some possible transformations)

2. Method should accept our Window instance as parameter and perform defined text line against parameter.

3. It should return something if we are requesting the property value.

So we need here something similar to the code we could write down manually in the application wrapped into a method, for example

this.Title = "NewTitle" can be imagined as following:

public static void SetTitle(Window obj, string value)
{
  obj.Title = value;
}

So upon processing the command our environment has to generate some method called for example "SetTitle", provide the execution context (in this case a Window) and pass the command typed by the user. During that it should redirect all "this" aliases to the execution context detected (in this case all "this" should be translated into "obj"). Regard this as you are typing the body of some method without body declaration and are sure that all the missing stuff will be automatically generated.

Implementation

Code generation for this case will require dealing with separate application domains due to assembly management issues and possible memory leaks. The steps will be as following:

1. Transform and wrap user defined method/function body with appropriate method, class, namespace, etc. declarations using the CodeDom (so to get the ready to compile sources either into memory or physical file)

2. Compile the resulting Dom into the assembly (I’ll be using physical files)

3. Create a separate application domain and load compiled assembly into it.

4. Extract the generated method from the loaded assembly and invoke it against the execution context (in this case it will be a Window)

5. Free resources, unload second application domain and perform a temporary files cleanup.

This is similar to implementing an Add-In or Plug-In support for your application where your external algorithms may be added to main application, executed against some provided execution context and finally destroyed without any impact on main application.

It is obvious that you might don’t want passing whole your window across application domain boundaries (i.e. .net Remoting scenario) and you don’t want marking anything as Serializable to pass into another domain. So all we need here is getting some delegate or lambda somewhere outside for applying it against our Window locally.

Void execution

Under Void execution I mean some operation that is invoked against your execution context and doesn’t return any results. For example setting the property value.

So what happens when user types this.Title = "New Title" and presses Enter or some "Execute" button

1. "this" alias is converted into "context"

2. Lambda action is generated that performs your logic against some "context" parameter:

Action<T> action = context => { context.Title = "New Title"; };

3. Wrapper method and class container is generated that will help you getting lambda from another domain:

namespace GraphSquare.AutoScript
{
  using System;
  using System.Windows;

  public class Script
  {
    public static Action<T> CreateLambda<T>() where T : Window
    {
      Action<T> action = context => { context.Title = "New Title"; }; 
      return action;
    }
  }
}

As you can see this method will be valid for all the types based on Window, so you’ll have possibilities running the resulting lambda against your different custom windows and dialogs that inherit Window type. Note that this rules are introduced for clarification purposes and <T> constraint may differ. According to this constraint we ensure that the method will be compiled successfully as each Window object has a Title property.

CodeDom for this method is generated using the Igor’s CodeDom extensions I mentioned at the beginning of the article:

public static CodeDom GenerateActionDom<T>(string actionBody)
{
  string body = string.Format(
    "Action<T> action = context => {{ {0}; }}; return action;",
    actionBody.Replace("this", "context"));

  CodeDom c = new CodeDom();
  c.AddReference(DefaultReferences)
      .AddNamespace(DefaultNamespace)
        .Imports(DefaultImports)
          .AddClass(
            c.Class(DefaultClassName)
              .AddMethod(c.LambdaAction("CreateLambda", typeof(T).Name, null, body))
           );

  return c;
}

I won’t dwell on extension methods implementation and my contribution to it as it is more understandable when looking through the sources. Please refer to the source code link at the end of this article. In two words you are creating the source for the class mentioned earlier and specifying the <T> constraint passing the generic type provided for the method. Also "this" alias is converted into "context" and passed to CodeDom as a body of newly generated method.

Function execution

If you want invoking the command that user had typed and expect some results to be returned and displayed you might want in this case getting Func<T,K> lambda, running it against some T parameter and present the K result back to user. For simplicity purposes I’ve decided to reuse native .net "return" keyword and so being close to method body declaration in a common way it is used.

So what happens when user types return this.Title and presses Enter or some "Execute" button:

1. "this" is converted into "context"

2. Lambda function is generated that performs some logic against your "context" and returns results

Func<T, object> func = context => { return context.Title; };

3. Wrapper function is generated for getting lambda from another domain, constraints and types are defined according to the calling application

namespace GraphSquare.AutoScript
{
  using System;
  using System.Windows;

  public class Script
  {
    public static Func<T, object> CreateLambda<T>() where T : Window
    {
      Func<T, object> func = context => { return context.Title; };
      return func;      
    }
  }
}

Here’s how CodeDom is generated to get such a class:

public static CodeDom GenerateFunctionDom<T>(string fucntionBody)
{
  string body = string.Format(
    "Func<T,object> func = context => {{ {0}; }}; return func;",
    fucntionBody.Replace("this", "context"));

  CodeDom c = new CodeDom();
  c.AddReference(DefaultReferences)
      .AddNamespace(DefaultNamespace)
        .Imports(DefaultImports)
          .AddClass(
            c.Class(DefaultClassName)
              .AddMethod(c.LambdaFunction("CreateLambda", typeof(T).Name, null, body))
           );

  return c;
}

Compilation and assembly loading

I’ve provided additional method for CodeDom class providing capabilities compiling sources to file without keeping the strong reference to Assembly file at the end so providing possibilities of removing the assembly later on when it is no more in use. You’ll be calling CodeDom.CompileAssembly method that gets string parameter for full final assembly path and returns CompilerResults for results processing in order compilation exceptions.

According to common approach patterns for loading assemblies inside separate application domains you need implementing a proxy Loader class to serve also as a contract and bridge between your two domains. So exactly the loader being instantiated in the second application domain will load compiled script assembly, extract the desired lambda and execute it against your context or simply return you the lambda so you can execute it inside the main application domain whenever required.

Assembly Loader

using System;
using System.IO;
using System.Reflection;

namespace GraphSquare.Scripting.CodeDom
{
  [Serializable]
  public class AssemblyLoader
  {
    Assembly assembly;

    public AssemblyLoader()
    {
      assembly = null;
    }

    // Loads the content of a file to a byte array to
    // prevent file locking, so user can remove or modify assembly 
    // while using it loaded into memory
    static byte[] LoadFile(string filename)
    {      
      FileStream fs = new FileStream(filename, FileMode.Open);
      byte[] buffer = new byte[(int)fs.Length];
      fs.Read(buffer, 0, buffer.Length);
      fs.Close();
      return buffer;
    }
    
    public void Load(string assemblyPath)
    {
      byte[] rawAssembly = LoadFile(assemblyPath);
      this.assembly = Assembly.Load(rawAssembly);
    }
  }
}

This is a basic implementation providing only assembly loading facilities. It will be extended later on. Note that it is situated in the separate assembly in order to serve a contract between different domains.

To create additional application domain our main application will have the following method:

private static AppDomain CreateNewDomain()
{
  // Create a simple application domain
  return AppDomain.CreateDomain(
    typeof(AssemblyLoader).Name, 
    AppDomain.CurrentDomain.Evidence, 
    AppDomain.CurrentDomain.SetupInformation);
}

This is the most basic implementation of second domain that takes Evidence and Setup Information from the main one and so loads all the references that the main domain has. In our case it will also load the contract library with the AssemblyLoader so we could establish communication between domains easily.

To create a valid loader in the second domain and loading external assembly file into it we’ll be using the following method:

private static AssemblyLoader CreateLoader(AppDomain domain, string assemblyPath)
{
  // Create a new instance of AssemblyLoader in the separate domain
  AssemblyLoader loader = domain.CreateInstanceAndUnwrap(
    "GraphSquare.Scripting", 
    typeof(AssemblyLoader).FullName) as AssemblyLoader;

  // Load compiled assembly into the loader
  loader.Load(assemblyPath);      
  return loader;
}

Extracting compiled lambdas

Fine now we have two possible members of the generated wrapper class needed to be discovered and loaded (action and function) to be used in lambda generation. As we have a separate domain with compiled assembly loaded into it and know exactly the namespace, type and name of the wrapper class and even the name of the method to generate lambda – "CreateLambda" (as we did it’s generation actually) the process of it’s loading and invokation becomes quite trivial.

Using Assembly.GetType(string…) method it becomes easy loading types and activating objects. For each type you can call GetMethod(…) to get the necessary method info to be used in invokaction. Thus discovering and invoking generic methods are a bit different. Here’s how can extract our generated "CreateLambda" method from AssemblyLoader:

public Action<T> GetLambdaAction<T>(string type, string action)
{
  // Extract type method info from assembly
  MethodInfo methodInfo = assembly.GetType(type).GetMethod(
    action, 
    BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static);

  // Create generic arguments for generic method
  Type[] genericArguments = new Type[] { typeof(T) };

  // Create generic function info for invokaction
  MethodInfo genericMethodInfo = methodInfo.MakeGenericMethod(genericArguments);

  // Invoke generic function and get return value as Action<T>
  Action<T> returnValue = (Action<T>)genericMethodInfo.Invoke(null, null);

  // return results
  return returnValue;
}

As compiled assembly is loaded into the second application domain where the AssemblyLoader is already present so loader is capable of discovering our generated type to work with further.

When executed this method returns us ready to use lambda with the body we defined earlier. In most of the cases guess you’ll have to get compiled lambda, execute it against some context and dispose it. So we can introduce two more members for the AssemblyLoader for invoking actions and functions directly from AssemblyLoader.

public bool InvokeLambdaAction<T>(string type, string action, T argument)
{      
  // Extract type method info from assembly
  MethodInfo methodInfo = assembly.GetType(type).GetMethod(
    action, 
    BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static);

  // Create generic arguments for generic method
  Type[] genericArguments = new Type[] { typeof(T) };

  // Create generic function info for invokaction
  MethodInfo genericMethodInfo = methodInfo.MakeGenericMethod(genericArguments);

  // Invoke generic function and get return value as Action<T>
  Action<T> returnValue = (Action<T>)genericMethodInfo.Invoke(null, null);
  if (returnValue != null)
  {
    // Execute received action against argument provided
    returnValue(argument);
    return true;
  }
  return false;
}

public object InvokeLambdaFunc<T>(string type, string function, T argument)
{
  // Extract type method info from assembly
  MethodInfo methodInfo = assembly.GetType(type).GetMethod(
    function, 
    BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static);

  // Create generic arguments for generic method
  Type[] genericArguments = new Type[] { typeof(T) };
  // Create generic function info for invokaction
  MethodInfo genericMethodInfo = methodInfo.MakeGenericMethod(genericArguments);
  // Invoke generic function and get return value as Func<T,K>
  Func<T, object> func = (Func<T, object>)genericMethodInfo.Invoke(null, null);
  //return execution result of func against the argument provided
  return func(argument);
}

As you can see both methods are not so different. Both of them require full type name of the class holding the method, method or function name to be searched and argument of your needed type to be processed as an execution context.

So the process of executing user typed command that doesn’t require results can be as following (at main application side):

// Generate CodeDom
CodeDom c = CodeDomSmith.GenerateActionDom<T>(methodBody);
string assemblyPath = GenerateAssemblyPath();
// Compile sources into assembly
CompilerResults results = c.CompileAssembly(assemblyPath);

// Process compilation errors
if (results.Errors.Count > 0)
  return false;

// Create separate application domain
AppDomain domain = CreateNewDomain();
// Create loader proxy based on application domain created 
// and load compiled assembly to it
AssemblyLoader proxy = CreateLoader(domain, assemblyPath);

try
{
  // Extract and execute lambda against the context object
  proxy.InvokeLambdaAction<T>(
    CodeDomSmith.DefaultClassFullname, "CreateLambda", context);
}
catch (Exception ex)
{
  return false;
}

if (domain != null)
{
  // Unload and dispose second application domain
  AppDomain.Unload(domain);
  domain = null;
}
if (File.Exists(assemblyPath))
  // Remove used assembly
  File.Delete(assemblyPath);

The only difficulty that arise is determining what type of lambda to generate according to the user input. I mean how to decide whether he wants executing a Void or getting some results. I’ve accomplished that again as I’ve mentioned earlier by reusing the "return" keyword. So due to this sample when the user starts the command from "return" keyword we are generating the Func<T,K> otherwise Action<T>

Samples:

Here’s the sample environment I’ve prepared for the article:

image

You’ll have the Window that will be assigned as an execution context for all upcoming commands typed in the bottom TextBox control.

"Execute" button compiles and executes the command putting all the output to the "Debug window" TextBox control. You will also be able to see the content of the class generated and executed for development purposes.

"Help" button shows a list of dummy samples that can be copy-pasted and tested against the window.

"Execution Result" TextBox shows the results of the command execution. This can be either "void()" if method was compiled and executed or some value.

Here’s the possible result of execution of the command:

this.Title = "GraphSquare Scripting"

image

Note that execution result is "void()" as we didn’t try to return anything and the Title of the window has changed from "Window1" to "GraphSquare Scripting"

Let’s try running the application once again and executing the following command:

return this.Title == "Window1"

image

As you can see command was successfully evaluated and returned "True" value that is a valid result as the Window’s Title property value is "Window1"

Now let’s try typing a command that cannot be valid and compiled by default, something like

this.ExecuteMissingCommand()

If you remember the execution context for our commands is being set to Window. This means that as a common Window class does not contain the method typed the resulting code won’t be compiled and cannot be executed against a window. This brings to a compilation exception:

image

The exception message will be the following:

error CS1061: ‘T’ does not contain a definition for ‘ExecuteMissingCommand’ and no extension method ‘ExecuteMissingCommand’ accepting a first argument of type ‘T’ could be found (are you missing a using directive or an assembly reference?)

This is mainly for your debugging purposes. The real life implementation can hide the developer oriented details and present more user-friendly message.

Also as you might have noticed all lambda generation methods are generic ones, for example

public static bool InvokeContextMethod<T>(T context, string methodBody, ...)

this means that you can specify different execution contexts or even change them on the fly.

As for the suggestions I think there could be some contracts to serve as execution context instead of applications or windows. Remember not providing the end-user more power that he is expected to have. As you will see from the samples provided within the "Help" section of this tool you can simply add or remove new elements to the window, rename buttons, etc.

Hope this helps someone enriching his tools with runtime command support or Debug features.

The source code for the article can be found here

Providing simple collaboration support for your diagramming tools with WCF services.


Notes: This article assumes you are already familiar with WCF services or studying them.

Several months ago I’ve posted simple draft project for a small diagramming tool. Though I didn’t intend it to be a tool or starter kit it is still the most visited post among all other more interesting things ;) As I’ve been playing with WCF and wanted some simple environment for testing some ideas I remembered about old CTP project and found it was quite a good playground for my experiments. So this article will be using the reviewed and edited version of the project mentioned in the old article.

I’d also recommend you visiting the Code Project to see the wonderful samples by Marcus. I’ve dared to take his toolbox and tool item implementation for my article samples :)

What is the key changes made since the previous sample:

1. Simple MVC pattern implementation sample

The classes introducing the pattern are:

DiagramView: WPF canvas hosting the shapes and connection lines

DiagramController: Simply the controller

DiagramModel: Data model hosting the business objects (entities) that are not related to presentation layer.

As my intention was processing business objects rather that shapes and controls I’ve decided to perform a dummy bridging between raw "DiagramEntity" classes and their UI representation.

I’ve also simplified event system between Model, Controller and View based on Action<DiagramEntity> delegates for clarity purposes. Model is capable only of storing the entities, adding them and removing. In this implementation the View is also responsible for instantiating the Collaboration Client that will be described later on.

2. Unity Application Block

I’ve reduced the influence of the service bus for many parts of the application in favor to Unity Application Block. That made my life much easier.

3. Toolbox

As I moved on for using a simple toolbox I’ve eliminated the shape tools and shape creators that were rudimentary parts of Factory design pattern. But left the connection creator tools with a simple Strategy pattern implementation just for educational purposes.

4. Extensions and IExtensibleObject<T> interface

In this article I’ve described some ideas for extending Canvas panels by means of IExtensibleObject<T> interface taken from WCF. I’ve decided it would be fair enough reusing this stuff to show that it’s working fine. The Canvas (View) is extended with Selection and Drag functionality that can be simple switched off if required.

5. Aero theme by default and many minor improvements…

Here’s how it looks like

image

 

Basic collaboration support using WCF service

My intention was giving some sketches for how it could be implemented and some raw material for starting to play with. So I’ll be concentrating on it omitting thread safeties, error checking and the stuff like that for clarity purposes. Guess it would be much easier extending the sources based raw skeleton implementation.

Business objects

Entities

As I’ve mentioned the entities my service will be operating on are not related to presentation layer so it won’t be aware of WPF and the stuff like that. It will be the View responsibility turning them into the visuals and applying different styles and templates. Meanwhile we need at least some basic UI related information be passed like positioning coordinates so this is what UIEntity class serves for. I’ll be playing with three entities named "DataEntity", "SystemEntity" and "UserEntity" that will be turned later on to the appropriate shapes at client side. This provides nice presentation flexibility allowing different clients using specific visuals and styles though following one remote model.

Remote Model and Remote Callbacks

I’ve chosen the Duplex WCF service for the sample that requires implementing a callback contract also. For more details on duplex services better refer to MSDN library as it might take long time for me describing theory that is already perfectly presented ;)

This is how the remote model might look like:

using System.ServiceModel;

namespace Collaboration.Contracts
{
  [ServiceContract(
    Name = "RemoteModel",
    Namespace = "http://dvuyka.spaces.live.com/diagramming/types",
    CallbackContract = typeof(IRemoteModelCallback),
    SessionMode = SessionMode.Required)]
  [ServiceKnownType(typeof(UserEntity))]
  [ServiceKnownType(typeof(DataEntity))]
  [ServiceKnownType(typeof(SystemEntity))]
  public interface IRemoteModel
  {
    [OperationContract(IsOneWay = true)]
    void AddEntity(DiagramEntity entity);

    [OperationContract(IsOneWay = true)]
    void RemoveEntity(DiagramEntity entity);

    [OperationContract(IsOneWay = true)]
    void Connect();
  }
}

Due to serialization purposes our model should be aware of all the inheritances that might take part in the collaboration process. I’ve declared them as "known" to the service being described by this interface. Our remote model will also provide Adding and Removing capabilities like the "local" tool’s model and subscription to service via the Connect method.

The callback contract might look like the following:

using System.ServiceModel;

namespace Collaboration.Contracts
{
  public interface IRemoteModelCallback
  {
    [OperationContract(IsOneWay = true)]
    void OnEntityAdded(DiagramEntity entity);

    [OperationContract(IsOneWay = true)]
    void OnEntityRemoved(DiagramEntity entity);
  }
}

It means that remote model (or simply service) will be raising "OnEntityAdded" and "OnEntityRemoved" events for all the subscribers providing them with the entities to be immediately added to the local model and so presented with the View.

Wiring up the "local" model

At the client side we are creating a simple wrapper delegating remote model events to the local model like the following

using Collaboration.Contracts;

namespace HomeDiagramming.Collaboration
{  
  public sealed class RemoteModelCallback : IRemoteModelCallback
  {
    public DiagramModel LocalModel { get; private set; }

    public RemoteModelCallback(DiagramModel localModel)
    {
      this.LocalModel = localModel;
    }

    #region IRemoteModelCallback Members

    public void OnEntityAdded(DiagramEntity entity)
    {
      this.LocalModel.AddEntity(entity);
    }

    public void OnEntityRemoved(DiagramEntity entity)
    {
      this.LocalModel.RemoveEntity(entity);
    }

    #endregion
  }
}

So each time the service will be publishing "OnEntityAdded" or "OnEntityRemoved" events to it’s subscribers the event execution will be delegated to the underlying local model by calling it’s appropriate members.

The client connecting our remote model will be as simple as possible:

using System.Diagnostics;
using System.ServiceModel;
using System.ServiceModel.Channels;
using Collaboration.Contracts;

namespace HomeDiagramming.Collaboration
{
  [DebuggerStepThrough]
  public class RemoteModelClient : DuplexClientBase<IRemoteModel>, IRemoteModel
  {
    public RemoteModelClient(InstanceContext callbackInstance) :
      base(callbackInstance)
    {
    }

    public RemoteModelClient(InstanceContext callbackInstance, Binding binding, 
EndpointAddress address)
      : base(callbackInstance, binding, address)
    {      
    }

    #region IRemoteModel Members

    public void AddEntity(DiagramEntity entity)
    {
      base.Channel.AddEntity(entity);
    }

    public void RemoveEntity(DiagramEntity entity)
    {
      base.Channel.RemoveEntity(entity);
    }

    public void Connect()
    {
      base.Channel.Connect();
    }

    #endregion
  }
}

During creation of the View that instantiates the Controller we can initialize our remote controller in the following way

InstanceContext context = new InstanceContext(new RemoteModelCallback(this.Controller.Model));
NetTcpBinding binding = new NetTcpBinding();
EndpointAddress address = new EndpointAddress("net.tcp://localhost:8080/RemoteModel");    
remoteModel = new RemoteModelClient(context, binding, address);
remoteModel.Connect();

Remote model skeleton

And finally here comes the raw skeleton for the remote model

using System;
using System.Collections.Generic;
using System.ServiceModel;
using Collaboration.Contracts;

namespace Collaboration.Service
{
  [ServiceBehavior(
    InstanceContextMode = InstanceContextMode.Single, 
    ConcurrencyMode=ConcurrencyMode.Multiple)]
  public class RemoteModel : IRemoteModel
  {
    // TODO: should be the thread-safe collections
    private List<DiagramEntity> entities = new List<DiagramEntity>();
    private List<IRemoteModelCallback> callbacks = new List<IRemoteModelCallback>();

    #region IRemoteModel Members

    public void AddEntity(DiagramEntity entity)
    {
      // TODO: should be performed in a thread-safe manner and fully async
      Console.WriteLine("Adding entity :" + entity.Name);
      lock (entities)
      {
        this.entities.Add(entity);        
      }

      Console.WriteLine("Entity added. Total count: " + entities.Count);
      IRemoteModelCallback callback = GetCallback();      
      foreach (IRemoteModelCallback c in callbacks)
        if (c != callback)
          c.OnEntityAdded(entity);
    }

    public void RemoveEntity(DiagramEntity entity)
    {
      // TODO: should be performed in a thread-safe manner      
    }

    public void Connect()
    {
      IRemoteModelCallback callback = GetCallback();
      if (!callbacks.Contains(callback))
      {        
        callbacks.Add(callback);
        Console.WriteLine("User connected. Total count: " + callbacks.Count);
      }
    }

    private IRemoteModelCallback GetCallback()
    {
      return OperationContext.Current.GetCallbackChannel<IRemoteModelCallback>();
    }

    #endregion
  }
}

As you can see it is a Singleton service with Multiple ConcurrencyMode. Each connected client will be registered within the subscribers collection (callbacks). Each model change causes all the subscribers to be notified.

In my implementation each client immediately applies changes to the Model and View. Guess the rest of functionality might depend on your ideas.

The source code for the article can be  found here:

Possible issues:

If you encounter exceptions related to connection try changing the ports for your endpoints. On some machines localhost:8080 may be not allowed. Change it to localhost:8000 ("App.config" for server and "DiagramView.cs" for client) or whatever port is available free and doesn’t violate your firewall policy.

Notes: In order to build solution you’ll need the release version of Unity Application Block. Solution is configured to run both service and demo application at a time. Open the binaries folder for demo application and run several instances of application in order to ensure all clients receive notifications and create shapes at a time.