Damon Payne: Hand waving Silverlight Architect

103db signal to noise ratio at < .03% total harmonic distortion
Solution Architect, software developer, geek
Damon Payne at Blogged
2009 Microsoft MVP - Client App Dev
2007 Microsoft MVP - Solution Architecture
 Monday, August 16, 2010

This weekend (Saturday morning) I'll be giving an advanced MEF talk at the St. Louis day of .NET. You can find details here I hope to see some familiar faces there!

When last I looked, this was the only MEF talk at the conference, so I'll try not to suck.



Monday, August 16, 2010 11:14:26 AM (Central Standard Time, UTC-06:00)  #    Disclaimer  |  Comments [5]  |  Trackback
 Thursday, July 22, 2010

Next week Thursday in Grayslake, Illinois I’ll be speaking on one of my favorite new topics, in this case MEF !

You can find directions and register here:

http://www.lcnug.org/Home.aspx

I have a great deal of both entry-level and advanced MEF content and how much we get through will depend upon the attendees.  I’ll be using mostly Silverlight and WPF to demonstrate different bits of MEF-Fu though there may be some surprises too…



Thursday, July 22, 2010 8:02:46 PM (Central Standard Time, UTC-06:00)  #    Disclaimer  |  Comments [4]  |  Trackback
 Sunday, July 18, 2010

I was out of the country last week.  I managed to not touch a computer or Smartphone of any kind for eight full days.  I even made my wife use the check-in kiosks in the airport.

To everyone who contacted me as part of their recruiting efforts, or were seeking to learn the identities of the MSDN subscription winners, or had technical presentation related questions, I apologize.  I don’t advertise the fact that I won’t be home on the same blog where you can find pictures of my toys ;).

This is only the second time my wife and I have been able to get out together for a no-kids vacation. 

DamonChitzenItza



Sunday, July 18, 2010 10:21:20 PM (Central Standard Time, UTC-06:00)  #    Disclaimer  |  Comments [6]  |  Trackback
 Monday, July 05, 2010

It’s often very useful to know when an object we are editing has Changed.  The most iconic example is the “*” that used to appear next to the title of Word documents once you’d made the first change no matter how small.  It’s not an unusual request that a “Save” button be disabled until the User has made a savable change.  This is often referred to as an object being Dirty.

This article is part of a series about useful MVVM friendly features for your data objects and favoring composition over inheritance.  You can read the other parts:

Dirty Aware

Now that we’ve introduced the idea of Property Change Behaviors, it’s easy for us to flag an object as having changed when we set any property value.  Let’s refer back to the BBGrill object in the Metro BBQ sample application.  I find it’s useful to standardize the HasChanges/Dirty state using an interface. 

/// <summary>
/// Capable of storing and notifying Dirty/HasChanged state
/// </summary>
public interface IDirtyAware
{
    bool IsDirty { get; set; }
    bool SuspendChangeNotification { get; set; }
}

We can now author a new IPropertyChangedBehavior that deals with IDirtyAware instances and sets their IsDirty flag to true whenever a property value changes.

public class DirtyPropertyBehavior : IPropertyChangedBehavior
{
    /// <summary>
    /// 
    /// </summary>
    /// <param name="owningInstance"></param>
    public DirtyPropertyBehavior(IDirtyAware owningInstance)
        : this(owningInstance, new List<string>() {"IsDirty"})
    {

    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="owningInstance"></param>
    /// <param name="exclusions"></param>
    public DirtyPropertyBehavior(IDirtyAware owningInstance, List<string> exclusions)
    {
        _owner = owningInstance;
        _propertyExclusions = exclusions;
    }

    IDirtyAware _owner;
    List<string> _propertyExclusions;

    /// <summary>
    /// 
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="owningInstance"></param>
    /// <param name="oldVal"></param>
    /// <param name="newVal"></param>
    /// <param name="propertyName"></param>
    /// <returns></returns>
    public bool PropertyChanged<T>(object owningInstance, T oldVal, T newVal, string propertyName)
    {
        if (!Object.Equals(oldVal, newVal) 
            && !_propertyExclusions.Contains(propertyName)
            && !_owner.SuspendChangeNotification)
        {
            _owner.IsDirty = true;
        }
        return true;
    }
}

Note that we can easily provide the ability to exclude certain properties from setting IsDirty, which is very useful for the IsDirty property itself.

Obviously we could put this functionality right inside the property setters but we want to make it easy to add/remove behaviors to objects.

Dirty Grill

Going back to the Metro BBQ sample application, I can now make BBQGrill implement IDirtyAware and also use the DirtyPropertyBehavior to flag when any change has been made.

public class BBQGrill : BindableType, INotifyDataErrorInfo, IDirtyAware
{
    public BBQGrill()
    {
        _changeBehaviors.Add(new DirtyPropertyBehavior(this));

Now, this is useful as we can key business logic off of the IsDirty property, however we can also bind to it in the UI which is just as useful.  Recall the Ideal Grill survey page from Metro BBQ.  We wanted to only enable the Save and Rest buttons once the user had made changes.  Now it’s easy to do so:

 <Button Content="Submit" Margin="10,0,10,0" IsEnabled="{Binding Grill.IsDirty}" />
 <Button Content="Reset" Margin="10,0,10,0"  IsEnabled="{Binding Grill.IsDirty}" />

This gives us the effect that we want in the UI for any property with extremely little code.

Screen default state:

buttonsdisabled

After changing one property:

buttonsenabled

Because of the way we structured Property Change Behaviors we just got a Binding-friendly “is dirty” behavior on all properties of the BBQGrill object.  Once we wrote the DirtyPropertyBehavior we got this essentially for free on all properties without writing extra code for every property.

Suspend Notifications

You may already be thinking of situations where you’d like to temporarily turn this property behavior off.  For example, you might be populating BBQGrill object values from a WCF service and obviously invoking property setters in that situation should not instantly mark the object as Dirty or this feature won’t be very useful.  You may have noticed that the IDirtyAware interface included a SuspendChangeNotification property and that the DirtyPropertyBehavior pays attention to this and does not set IsDirty when SuspendChangeNotification is set to true.  This solves the re-entrant problem but we can do a little better in terms of the developer experience around this code using a context class.

/// <summary>
/// Enable nice using(){} semantics for setting property values without firing Dirty state behaviors
/// </summary>
public class SuspendDirtyContext : IDisposable
{
    public SuspendDirtyContext(IDirtyAware target): this( new List<IDirtyAware> { target } )
    {
    }

    public SuspendDirtyContext(IEnumerable<IDirtyAware> targets)
    {
        _targets = targets;
        int index = 0;
        _targets.ForEach(d => 
        {
            _previousValues[index] = d.SuspendChangeNotification;
            d.SuspendChangeNotification = true;
            ++index;
        });
        _previousValues = new bool[_targets.Count()];
    }

    IEnumerable<IDirtyAware> _targets;
    bool[] _previousValues;

    public void Dispose()
    {
        int index = 0;
        _targets.ForEach(d =>
            {
                d.SuspendChangeNotification = _previousValues[index];
                ++index;
            });
    }
}

In C#, classes that implement IDisposable can be used in using() blocks.  While we’re not really getting rid of any resources here the syntactical sugar is too good to pass up. This SuspendDirtyContext allows us to write nice readable code like the following:

var bbqGrill = new BBQGrill();
using (var ctx = new SuspendDirtyContext(bbqGrill))
{
    //... set initial values
}

The using() block in C# winds up creating try/catch/finally semantics in IL, so even if something causes an exception to be thrown our object state won’t be wonky outside of this scope.  As you can see the SuspendDirtyContext can also handle more than one IDirtyAware instance. 

Conclusion

Knowing when a user has made a change to a data entity through the UI is a commonly requested and useful feature, and implementing it can be pretty easy with the right design of your data entities.  Using the Composition approach makes it very easy to turn this feature on and off for different objects or even different instances of the same type depending on your needs. 

There are still situations that can be easily supported using the same techniques we’ve already demonstrated and these will be explored in the following articles. 



Monday, July 05, 2010 7:33:05 PM (Central Standard Time, UTC-06:00)  #    Disclaimer  |  Comments [10]  |  Trackback
 Sunday, July 04, 2010

I have in hand a couple of one year MSDN Subscriptions with Visual Studio 2010 Ultimate.  Never you mind where they came from, but they didn’t fall of the back of a truck, they are legitimate. 

These are not for me, they are for YOU.  However, there are only two of these and according to my quick Twitter poll, a lot more than two people who’d like their own MSDN Ultimate.  Therefore, I pose to you a very simple contest.  Leave me a comment or send me an email telling me why you should get a subscription.  I will choose the winners late this week.

{Edit: I should be clear: I’m looking for community influencers here.  Tell me how this prize will touch more lives than just your own}



Sunday, July 04, 2010 8:10:59 PM (Central Standard Time, UTC-06:00)  #    Disclaimer  |  Comments [10]  |  Trackback
 Thursday, July 01, 2010

I am honored to be re-awarded the Microsoft MVP award in the Client App Dev competency.  As others have pointed out, re-awardees have to be vetted just like new awardees – no coasting!  I couldn’t have achieved this without all of you out there who keep reading my blog and inviting me back to your user groups, code camps, and conferences.  I have big plans for the next year so please keep coming back!

Cheers,

Damon



Thursday, July 01, 2010 7:24:24 PM (Central Standard Time, UTC-06:00)  #    Disclaimer  |  Comments [7]  |  Trackback
 Thursday, June 24, 2010

Given the momentum behind MEF at Microsoft and the fact that MEF has shipped in the box with Silverlight 4, you may find it somewhat disappointing that MEF is not available for Windows Phone 7.  Due to low level differences in the CLR for Windows Phone 7, you can’t just grab MEF from Codeplex either – read on to see the solution.

The Goal

Given the Marketplace restrictions, we know that our application code must go through a QA process and be signed in order to be deployable to the Windows Phone 7 (henceforth The Phone, or WP7). It’s not surprising then that the popular Silverlight Dynamic Recomposition techniques using MEF and downloaded XAP files won’t work.  However, it’s still incredibly useful to be able to use DeploymentCatalog and friends to wire together components in an application.  Getting this scenario working on The Phone is how I’m defining success for now.

Getting MEF to Build and Run

Prior to .NET 4 and Silverlight 4 shipping MEF has been available in preview form on Codeplex.  I was surprised that, being a daily reader of Silverlightshow.net, I hadn’t already seen an article submitted by someone who had built MEF for Windows Phone 7.  Now I know why.

Trial 1 – Building MEF Preview 9 as a Silverlight 3 Project

Many Silverlight 3 assemblies will turn out to just work on The Phone.  It seems reasonable that the first thing to try is to get MEF Preview 9 from CodePlex.  You can build this as a Silverlight 3 project and then reference the binary output from a WP7 project.  Trying to use DeploymentCatalog immediately blows up at runtime though.  That would have been too easy.

Trial 2 – Referencing MEF Preview 9 as a Silverlight 3 Project with Source

Rather than just building and referencing System.ComponentModel.Composition and System.ComponentModel.Composition.Initialization as assemblies, I thought I’d add the source projects to my test solution and step through to see what was going on.  It could always be something simple and obvious.  I was getting some interesting MissingMethodException and MethodAccessException behavior so as feared this was likely going to involve source code modifications to get it working, if it was possible at all.  I moved on to the next logical choice.

Trial 3 – Building MEF as Windows Phone 7 Class Libraries

At this point I assumed some low-level binary incompatibility or missing Type was the issue so I decided to create two new WPF class library projects and add the respective MEF source files to these.  Building MEF using Windows Phone 7 Class Library as the project type would immediately show me any issues with base class library parity.   At this point I was confronted by three major issues I was previously unaware of.

No System.Reflection.Emit

I was always extremely happy that SRE was included in Silverlight, so I was a bit surprised to find it missing from The Phone.  Sure, we never had it in Compact Framework development but The Phone is a much more heterogeneous platform compared to the giant universe of Windows CE/Windows Mobile hardware.  This spells doom for some of my more advanced Silverlight development scenarios, and for certain MEF features as well.  MEF uses SRE to create dynamic implementations of interfaces for Metadata – very handy for Lazy Imports. 

I have a reasonably easy workaround for the Import Metadata issue, but eager to get my main success scenario working I commented this feature out for now and moved on.

No IQueryable

The MEF code uses a fair bit of IQueryable internally.  Not being familiar enough with LINQ Expression hacking I can’t fathom why this was left out.  Performance implications?  Required Reflection Emit?  I don’t know.  Nonetheless, this code had to be changed in places like TypeCatalog, AggregateCatalog, and the ComposablePartCatalog base class.  Until I at least got this to compile I wouldn’t know if IEnumerable would work as a surrogate for IQueryable or not.

{No IQueryable http://social.msdn.microsoft.com/Forums/en-US/windowsphone7series/thread/79858a29-4db0-460d-9a75-3630211a28fb/ }

No Dynamic Assembly Loading.  Period.

Silverlight XAP files are packaged with a Deployment Manifest that makes it easy to enumerate the assemblies included in a given XAP file.  In the Full versions of Silverlight you can use these AssemblyParts to load the assemblies and do useful things like add them to an AssemblyCatalog for MEF.

In their Zeal to prevent you from somehow loading code onto The Phone that had not gone through The Marketplace, you can’t load assemblies by name using this technique or any other technique.  Unfortunately this even includes assemblies that are hard-referenced by your WP7 Application.  What the harm would be in allowing developers to get a handle to all the assemblies that are hard-referenced is beyond me but this one is a showstopper.  Or is it?

We Can Continue, but Should We?

Suppose we can keep going.  Is MEF worthless in the Windows Phone 7 scenario given these limitations or is there still value to be had?  MEF is about Composition, Isolation, Separation, and Extensibility.  MEF is about programming against abstractions and making it easy for third parties who are unknown at compile time to extend your applications.  While some of these benefits cannot be realized given the WP7 limitations there are still meaningful benefits.

  1. Suppose you are developing frameworks and using MEF as your mechanism of wiring up Abstractions to their Implementations.  If you want to share any code with The Phone, it would suck to not at least be able to use MEF to map “IWidget to DefaultWidget”.  Programming against abstractions is always good.
  2. You may simply prefer the Import/Export programming model to alternatives like Factories and Service Locators.  Doing these things manually can take a lot of code.
  3. You may be used to ImportMany semantics, which is not a common feature in IoC containers that I know of.
  4. Microsoft may loosen up the WP7 deployment story in the future and you want to be ready.
  5. You love MEF and you have a Man-crush on  Glenn Block and you want to achieve Universal MEFness

The Current Workaround

For my part, I am working on frameworks that I’d like to recompile for Windows Phone 7, and I’ve become very accustomed to the great programming model MEF enables.  I’m NOT going to manually register every single Type I use to get around the DeploymentCatalog issues though.  Given that we can’t load assemblies by name, is there any compromise we can make?  Yes there is.

Since we can only hard-reference assemblies for Windows Phone applications, we can cheat and get a handle to each assembly we want to participate in Composition by using any Type from each assembly.  By then modifying DeploymentCatalog to add an additional constructor we can at least run some sample code and see what’s working and what’s not.  I went ahead and created a Mobile version of the Metro BBQ example I’ve been using lately.  I have an entry point application and two module assemblies and I’d like to to use MEF to glue them all together.

projects

In the entry point application there is a simple UI that displays Gas Grills and Charcoal Grills, and I’d like to create a simple ViewModel that gets populated with IGrill implementations via MEF Catalogs.

namespace MetroBBQ.Mobile
{
    public class ShellViewModel : INotifyPropertyChanged
    {
        private IEnumerable<IGrill> _AllGrills;

        [ImportMany]
        public IEnumerable<IGrill> AllGrills
        {
            get { return _AllGrills; }
            set
            {
                _AllGrills = value;
                OnPropertyChanged("AllGrills");
            }
        }              

        public event PropertyChangedEventHandler PropertyChanged;

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

Now using some bootstrapper types from each assembly along with my DeploymentCatalog modifications, I create a CompositionContainer, and give it all a try.

private void PhoneApplicationPage_Loaded(object sender, RoutedEventArgs e)
{
    var shimTypes = new List<Type> { typeof(MetroBBQ.Mobile.GasGrills.Bootstrapper), typeof(MetroBBQ.Mobile.CharcoalGrills.Bootstrapper), GetType() } ;
    var deploymentCatalog = new DeploymentCatalog(shimTypes);
    var container = new CompositionContainer(deploymentCatalog);
    var vm = new ShellViewModel();
    container.ComposeParts(vm);
    DataContext = vm;
}

Sure enough, I’m now able to Compose Parts just like my MEF experience on other platforms.  There are a LOT of other scenarios to test but I’m encouraged by this initial success.  My ViewModel gets populated with IGrill implementations from two other assemblies in my Windows Phone 7 application.

GrillsScreen

What do you think, dear reader?  Is it worth doing more testing or shall I add this to the collection of forgotten novelties on my shelf?  Would you like the source code?  Is this worthy of MEFContrib? Leave me a comment!  For my part, I’m happy to be able to continue my MEF experience on this new platform.



Thursday, June 24, 2010 9:52:19 PM (Central Standard Time, UTC-06:00)  #    Disclaimer  |  Comments [18]  |  Trackback
 Sunday, June 20, 2010

In the next article in this series, I introduce the idea of Property Change Behaviors.  This concept is used to provide a means of easily attaching useful features to data objects.  Any number of features can be added without requiring a complex inheritance structures or keeping you from configuring the features on a per-property or per-instance basis.

This article is part of a series about useful MVVM friendly features for your data objects and favoring composition over inheritance.  You can read the other parts:

Can we all agree to call Silverlight/WPF development “XamlWorld” ?

Introducing Property Change Behaviors

Recall that we opened the first article with a list of actions we might want to take when a property on a XAMLWorld data object changes:

  1. Firing change notification
  2. Handling property-level validation
  3. Tracking when an object has changed (dirty/change tracking)
  4. Update dependent or calculated properties
  5. Providing Undo support

It would be ideal if we could provide a mechanism to do all of these things, and whatever else we think of in the future, in a generic fashion.  Since XAML technologies provide fantastic data binding support centered around the notion of CLR Properties, connecting our behaviors to properties is a very good approach.  If you want to use anything that’s built into XamlWorld, you need to make peace with the notion that The Property is the coin of the realm. 

We can think of Property Changed Behaviors as a sort of “visitor” or “Chain of Responsibility”.  Here is the interface for Property Change Behaviors:

public interface IPropertyChangedBehavior
{
    /// <summary>
    /// Do something useful when a property changes
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="owningInstance">Object instance whose property has changed</param>
    /// <param name="oldVal">current property value</param>
    /// <param name="newVal">new property value</param>
    /// <param name="propertyName"></param>
    /// <returns>Returns true of more behaviors can keep processing</returns>
    bool PropertyChanged<T>(object owningInstance, T oldVal, T newVal, string propertyName);
}

There are more complex scenarios for IPropertyChangedBehavior, but for this series of articles we’ll stick with the first draft.  This interface allows us to do interesting things when Property values change.

Remember what our BindableType property setter looked like previously?  Recall that we did this to avoid re-creating the basic INotifyPropertyChanged implementation over and over:

protected void OnPropertyChanged(string propName)
{
    if (null != PropertyChanged && !SuspendChangeNotification)
    {
        PropertyChanged(this, new PropertyChangedEventArgs(propName));
    }
}

In order to move forward I’ve changed the semantics somewhat.  The code snippet for setting properties in this style is provided at the end of this article.  Keeping with the Metro BBQ example from the previous article, here’s what the properties look like on my BBQGrill class.

Materials _KettleMaterial;

public Materials KettleMaterial
{
    get { return _KettleMaterial; }
    set { Set<Materials>(ref _KettleMaterial, value, "KettleMaterial"); }
}

This allows me to use semantics like the following on the BindableType base class.  Yes, we’re still extending BindableType for now, one step at a time.  We will eventually refactor to avoid the need to extend BindableType.

protected void Set<T>(ref T local, T newVal, string name)
{            
    T localCopy = local;
    local = newVal;

    if (null != _changeBehaviors)
    {                
        foreach (var behavior in _changeBehaviors)
        {
            bool @continue = behavior.PropertyChanged<T>(this, localCopy, newVal, name);
            if (!@continue) { break; }
        }
    }
    else//no behaviors, just carry on with the old way
    {
        OnPropertyChanged(name);
    }                
}

Now things are starting to get interesting.  BindableType has an instance variable to contain the IPropertyChangedBehaviors we want to use.

protected IEnumerable<IPropertyChangedBehavior> _changeBehaviors;

Each object now has a configurable list of interesting actions that we can go through any time a property value changes.  Based on the fact that we’d like to enable Binding updates, the choice for the first IPropertyChangedBehavior implementation is obvious:

public class NotifyPropertyBehavior : IPropertyChangedBehavior
{
    public NotifyPropertyBehavior(INotifyPropertyChanged target, Action<string> changedCallback)
    {
        Requires.NotNull(target, "target cannot be null");
        Requires.NotNull(changedCallback, "changedCallback cannot be null");
        Target = target;
        ChangeCallback = changedCallback;
    }

    public INotifyPropertyChanged Target { get; set; }

    /// <summary>
    /// Needed since only the owning instance can fire the event
    /// </summary>
    public Action<string> ChangeCallback { get; set; }


    /// <summary>
    /// Fire change notification only if the new value != old
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="owningInstance"></param>
    /// <param name="oldVal"></param>
    /// <param name="newVal"></param>
    /// <param name="propertyName"></param>
    /// <returns></returns>
    public bool PropertyChanged<T>(object owningInstance, T oldVal, T newVal, string propertyName)
    {
        if (!Object.Equals(oldVal, newVal))
        {
            ChangeCallback(propertyName);
            return true;
        }
        else
        {
            return false;
        }
    }
}

… and in the constructor of BindableType, we create the following defaults used in the Setter, above:

_changeBehaviors = new List<IPropertyChangedBehavior>

{ new NotifyPropertyBehavior(this, s=> OnPropertyChanged(s) ) };

Now, we are in a situation where our data objects can have any number of IPropertyChangedBehaviors attached.  For now, the NotifyPropertyBehavior has merely replaced how we fire change notification, but the behaviors shown in the following articles will implement much more interesting functionality.

PropertyChangedBehaviorCD

Conclusion

So, we’ve created some basic functionality for iterating through an ordered list of interesting actions whenever a property value changes.  Based on the logic inside BindableType, if the property values are equal we would stop processing subsequent Property Change Behaviors for this instance by returning false from NotifyPropertyBehavior.

In the next article we’ll start adding more useful and interesting features using the IPropertyChangedBehavior approach.

Download the bprop code snippet.



Sunday, June 20, 2010 2:23:27 PM (Central Standard Time, UTC-06:00)  #    Disclaimer  |  Comments [7]  |  Trackback