How Autofac’s Dynamic instantiation solves the service locator problem for ViewModels

Yesterday ive blogged about why I moved to Autofac. Now I want to show a really nice feature of Autofac which solves the service locator problem when you work with child ViewModels.

Let me give this example:

public class OrderViewModel
{
    public ObservableCollection<OrderLineViewModel> OrderLines { get; set; }

    public OrderViewModel(OrderDao orderDao)
    {
        OrderLines = new ObservableCollection<OrderLineViewModel>();

        foreach(var orderLine in orderDao.GetOrderLines())
        {
            var viewModel = IoC.Resolve<OrderLineViewModel>(orderLine);
            OrderLines.Add(viewModel);
        }
    }
}

What is the problem here? We need to create an OrderLineViewModel for each OrderLine we get from the database. We can not know how much OrderLines we need at build time of the OrderViewModel so we can not use constructor inject for that.

We have to use IoC.Resolve which is commonly known as service locator pattern. The real problem with that is that such a call only fails (because of missing dependencies) when it happens not on that point where the constructor of the root is resolved. In this example weights not much, but if this happens to code which is only used once in a month you have a problem.

So how Autofac can solve that:

public class OrderViewModel
{
    public ObservableCollection<OrderLineViewModel> OrderLines { get; set; }

    public OrderViewModel(OrderDao orderDao, Func<OrderLineViewModel,OrderLine> orderLineViewModelFactory)
    {
        OrderLines = new ObservableCollection<OrderLineViewModel>();

        foreach(var orderLine in orderDao.GetOrderLines())
        {
            var viewModel = orderLineViewModelFactory(orderLine);
            OrderLines.Add(viewModel);
        }
    }
}

What is the difference? The func is a dynamic service locator provided by Autofac, but instead at call time, Autofac has now the chance to know what types you need at runtime and now it can satisfy all dependencies at resolve time of the root objects constructor.

So what happens is that it fails now at the root of you application. Not one month later when your client calls this one view with the missing dependencies.

The same way Autofac supports Lazy<T> which is new in .Net 4.0 and resolves once on the first call. You can read more about that in this blog post from Nicholas Blumhardt which is the author of Autofac.

CommandProxy: Howto databind a ICommand to an InputBinding

When you start using the ViewModel pattern in WPF, some day you stumble upon that it is not possible to databind an command to an MouseBinding or KeyBinding.

So why this is not possible?

The WPF DataBinding’s are heavily based on DependencyPropertys which are only work on objects which inherit from DependencyObject. But the Command property on Mouse- and KeyBinding isnt an DependencyProperty. So DataBinding will not work on them.

The next problem is that the InputBinding class is only derived from DependencyObject and so it has no inheritance context which allow to get access to DataContext and ElementName.

May it is a performance consideration, may it is mistake, finally i dont know why they make this decision.

So how to make the DataBinding work anyway?

My solution is called CommandProxy and it uses a simpified version of Josh Smith Virtual Branch technic.

So here the CommandProxy looks like:

    public class CommandProxy : Freezable, ICommand
    {
        protected override Freezable CreateInstanceCore()
        {
            return new CommandProxy();
        }

        public static readonly DependencyProperty CommandProperty =
            DependencyProperty.Register( "Command",
                typeof(ICommand),
                typeof(CommandProxy),
                new UIPropertyMetadata() );

        public ICommand Command
        {
            get { return (ICommand)GetValue( CommandProperty ); }
            set { SetValue( CommandProperty, value ); }
        }

        public void Execute( object parameter )
        {
            Command.Execute( parameter );
        }

        public bool CanExecute( object parameter )
        {
            return Command != null && Command.CanExecute( parameter );
        }

        public event EventHandler CanExecuteChanged
        {
            add { CommandManager.RequerySuggested += value; }
            remove { CommandManager.RequerySuggested -= value; }
        }
    }

And here is how to use it:

    <Grid Background="LightGreen">

        <Grid.Resources>

            <a:CommandProxy x:Key="TestCommand"
                    Command="{Binding TestCommand}" />

        </Grid.Resources>

        <Grid.InputBindings>

            <MouseBinding Command="{StaticResource TestCommand}" Gesture="LeftClick" />

        </Grid.InputBindings>

        <TextBlock Text="click here" VerticalAlignment="Center" TextAlignment="Center" />

    </Grid>

As the name suggests, all this class dose is to expose a ICommand interface and redirect its methods to the databound command. The inheritance context problem is resolve by inherting from Freezable. You can read more about why Freezable helps here, in Dr. WPFs Blog here.

Download the CommandProxySample Visual Studio 2008 Solution.