Presentation: QMSDNUG Smart Client Patterns

I gave a presentation last night at the Queensland MSDN User Group on Smart Client Patterns. We covered the following:

I used PowerPointPlex in the slide deck to add a bit of jazz to the slides and help communicate the structure of the talk.

You can get the sample code and slide deck from Subversion here:

http://svn.paulstovell.com/Presentations/Pattern%20Safari/

Rob Sanders did a surprise presentation at the end on SQL Data Services which was received very well. Check out his blog for more of his thoughts on SDS.

Thanks everyone who came along and made it a good night.

Overheard: WPF 4 and Fonts

This is an interesting comment from Soma on his .NET 4.0 post. Torsten Koehler asks:

We are currently working on a Silverlight app and the blurry fonts have become a major issue.  I am assuming this will be addressed by WPF4.  Do you have a rough ETA that we can pass on to our clients?

To which the reply is:

Yes, we are planning on addressing these in WPF4.  You will likely see pixel snapping in a beta release and improvements to the blurry font issue at RTM.  It is a little too early to talk about an ETA, but as we make more progress on .NET FX4, we will keep you posted.

I’ll be very happy.

Dino!

Watching the various announcements coming out of the PDC, you’ve probably come to the realization that the web is dead, and rich client technology is the future. Not convinced? Well, if you’re sure you still want to build on the web, then why not learn it from one of the best in the business: Dino Esposito!

image

Here’s a brief overview:

For the first time in Australia, Dino Esposito will deliver his Next Generation Web Applications Master Class as part of Readify’s Industrial Strength Series. Dino is an MVP based in Italy and is considered an authoritative and acknowledged world expert in Web applications built with .NET technologies.

During this five-day intensive course, the problem of AJAX architectures and the Web in general will be discussed to identify an easy and a not-so-easy way to AJAX with their positives and negatives, their features and drawbacks. Students should devise an AJAX presentation layer as a two-tier model with a JavaScript-powered front-end and a multi-layer service-based back-end communicating over HTTP and using JSON feeds. It looks like a plan, but the devil is in the details… Which services should you use? REST, WS-*, WCF, or just a remote API? Should you create the user interface programmatically in JavaScript or have it generated as mark-up on the server? Is it worth considering client technologies more powerful than JavaScript? And a delivery format for the application that is more descriptive than HTML.

Course Highlights:

Day 1- ASP.NET AJAX—The Easy Way

  • AJAX: Nutrition Facts and the Starvation of the Classic Web Architecture
  • Orchestrating AJAX in ASP.NET
  • Adding AJAX Capabilities to ASP.NET
  • Real-world Partial Rendering

Day 2- ASP.NET AJAX—The Not-So-Easy Way

  • Power to the Client
  • Aspect-oriented AJAX
  • Common Problems and AJAX Patterns
  • The Service Layer

Day 3 - ASP.NET State-of-the-Art

  • LINQ at a Glance
  • LINQ for (ASP.NET) Architects
  • ASP.NET 3.5—What’s New
  • ASP.NET 3.5 Service Pack 1

Day 4- The (Deep) Impact of Silverlight

  • Silverlight and AJAX
  • Essential WPF
  • Scripting the Silverlight Engine
  • Silverlight 2.0

Day 5- Building RIA with Silverlight

  • Fundamentals of RIA with Silverlight
  • Networking and I/O
  • Architecture and Programming Model
  • One XAML Fits All

So what are you waiting for?

WPF: Dependency Injection in XAML

Sometimes you will build custom controls that you wish to create in XAML, but those controls may have a dependency on a service which you want to be provided by your dependency injection container.

Assuming your control is declared like this:

class CurrencyControl : Control
{
    public ICurrencyConverter CurrencyConverter { get; set; }
    public ICurrencyDescriptor FromCurrency { get; set; }
    public ICurrencyDescriptor ToCurrency { get; set; }
}

(Of course, each of those properties would be dependency properties.)

You could declare it in XAML:

<z:CurrencyControl
    x:Name="_currency"
    FromCurrency="{Binding Path=SelectedProduct.Currency}"
    ToCurrency="{Binding Path=UserProfile.Currency}"
    />

And then set the property using codebehind:

public Window1()
{
    InitializeComponent();
    _currency.CurrencyConverter = ServiceLocator.Current.GetInstance<ICurrencyConverter>();
}

A nicer way to do this is to use a MarkupExtension to tell the container to resolve the service. It might look like this:

<z:CurrencyControl
    CurrencyConverter="{z:ResolveDependency Type={x:Type z:ICurrencyConverter}}"
    FromCurrency="{Binding Path=SelectedProduct.Currency}"
    ToCurrency="{Binding Path=UserProfile.Currency}"
    />

Or, since the markup extension has access to the property that the value is being set on, you could infer the correct service type to resolve based on the property type, leaving:

<z:CurrencyControl
    CurrencyConverter="{z:ResolveDependency}"
    FromCurrency="{Binding Path=SelectedProduct.Currency}"
    ToCurrency="{Binding Path=UserProfile.Currency}"
    />

Such a markup extension would look like this:

[MarkupExtensionReturnType(typeof(object))]
public class ResolveDependency : MarkupExtension
{
    public ResolveDependency()
    { }

    public ResolveDependency(Type type)
    {
        Type = type;
    }

    [ConstructorArgument("type")]
    public Type Type { get; set; }

    public override object ProvideValue(IServiceProvider serviceProvider)
    {
        if (serviceProvider != null)
        {
            var provideValueTarget = (IProvideValueTarget)serviceProvider.GetService(typeof(IProvideValueTarget));
            if (provideValueTarget != null)
            {
                var targetObject = provideValueTarget.TargetObject as DependencyObject;
                if (targetObject != null)
                {
                    // If the type isn't specified, infer it from the property being assigned
                    var resolve = Type;
                    if (resolve == null)
                    {
                        if (provideValueTarget.TargetProperty is DependencyProperty)
                        {
                            resolve = ((DependencyProperty) provideValueTarget.TargetProperty).PropertyType;
                        }
                    }

                    if (resolve == null)
                    {
                        throw new Exception("...");
                    }

                    return ServiceLocator.Current.GetInstance(resolve);
                }
            }
        }
        return null;
    }
}

In fact, you could go so far as to resolve a whole control this way:

<ContentPresenter Content="{z:ResolveDependency Type={x:Type z:IUserView}}" />

You can go further by adding a design-time value, for when your IOC container is not available:

public Type DesignTime { get; set; }

// In your MarkupExtension:
// At design time, return an instance of the DesignTime type
var isDesignMode = DesignerProperties.GetIsInDesignMode(targetObject);
if (isDesignMode && DesignTime != null)
{
    try
    {
        return Activator.CreateInstance(DesignTime, true);
    }
    catch (Exception ex)
    {
        throw new Exception(string.Format("An exception occured while evaluating {0}. The DesignTime type '{1}' could not be instantiated. Please see the InnerException for more details. Message: {2}", this.ToString(), DesignTime.ToString(), ex.Message), ex);
    }
}

Making the XAML:

<z:CurrencyControl
    CurrencyConverter="{z:ResolveDependency Type={x:Type z:ICurrencyConverter}, DesignTime={x:Type z:DesignerCurrencyConverter}"
    FromCurrency="{Binding Path=SelectedProduct.Currency}"
    ToCurrency="{Binding Path=UserProfile.Currency}"
    />

If your IOC container is not available as a static object, one approach would be to use an attached inherited dependency property, and to set that at the root of your Window.

IOC: Discoverable Services with Extension Methods

I posted a review contrasting Composite WPF with the implementation of the Expression Framework. One area that stuck with me was how much I liked the discoverable nature of the Expression IApplicationService, even though it is essentially an IOC container. The problem is you can only add so many methods to your IApplicationService before it becomes difficult to manage - how can other assemblies "contribute" application-wide services?

Jared Roughan (he doesn’t have a blog - boo!), my colleague from Readify, was doing some work using the Composite WPF Event Aggregator, and had a similar problem: he wanted to make the types of events discoverable. He did this by creating extension methods, and placing them at the root namespace of the module, so that they would be clearly available anywhere within the module.

Winding back, when you use the Composite WPF event aggregator, you tell it you want to subscribe to an event like so:

eventAggregator.GetEvent<CustomerSelectedEvent>().Subscribe(HandleBroadcast_CustomerSelected);

The problem is that callers to this API may not know all of the different types of events available for subscription, especially if they are provided by external modules.

An extension method to add discoverability to this interface might look like this:

public namespace Microsoft.Practices.Composite.Events
{
    public static class CustomerEventExtensions
    {
        public static SubscriptionToken WhenCustomerSelected(
            this IEventAggregator eventAggregator,
            Action<CustomerSelectedEvent> callback
            )
        {
            return eventAggregator.GetEvent<CustomerSelectedEvent>.Subscribe(callback);
        }
    }
}

This gives anyone who has a reference to the IEventAggregator the following API, which is much nicer in my book:

eventAggregator.WhenCustomerSelected(HandleBroadcast_CustomerSelected);

What I also like about this, is that since extension methods are resolved simply by having a reference to the assembly, and by using the namespace (which happens automatically 99% of the time if you extend the interface’s namespace). Therefore, any assemblies you reference will automatically "contribute" methods to the interface. I like to think of it as compile-time injection :)  

You could apply this concept to your IOC container for application-wide services. For example, you might extend the Common Service Locator as the IOC interface you pass around your objects:

namespace MyApplication
{
    public interface IApplicationService : ICommonServiceLocator
    {
    }
}

Then from anywhere in the application, in any assembly, it can be extended to add discoverability:

namespace MyApplication
{
    public static RegionExtensions
    {
        public static IRegionManager GetRegionManager(this IApplicationService applicationService)
        {
            return applicationService.GetInstance<IRegionManager>();
        }
    }
}

I think this does a great job of solving the discoverability problem while still making maintenance easy. What do you think?