Thursday, October 27, 2011

M-V-VM: simple view provider

On these pages I have spoken a lot, during this years, about UI composition and I’ve also built a toolkit (during the Prism v1 era) to automate all the infrastructure and all the basic tasks related to UI composition.
That project, named Ran Toolkit, has been developed for about 4 years,  and gave me lots of satisfactions, but:
  • has grown uncontrolled, introducing unwanted complexity…the typical big ball of mud;
  • has a double face: it’s a m-v-vm toolkit and an UI composition toolkit, and if you want one you have to get the other…and vice versa…not the best;
A couple of months ago I started a new WPF project, at a first glance a really simple project, with really basics m-v-vm needs that can be satisfied by Radical and a base class that implements INotifyPropertyChanged, nothing more.
So far, so good…
Obviously that small application evolved and start asking for some UI composition feature, so I decided to give to the Ran Toolkit a new life adding a new kid to the Radical family: Radical.Windows.Presentation (not yet on nuget).
So what?
The aims of Radical.Windows.Presentation are:
  • provide a m-v-vm toolkit;
  • provide a UI composition toolkit;
  • remove, totally remove, the coupling between the two toolkits letting the developer choose what he needs, without compromises;
The main pillar of Radical.Windows.Presentation is: simplicity (period).
With simplicity in mind the first thing I approached is the Inversion of Control container support, specifically how to help the developer to resolve views and view models.
I can state that there is a tight coupling between views and view models, at least most of the times for every single view there is a view model, what a better place to introduce conventions?
public interface IViewResolver
{
T GetView() where T : DependencyObject;
}
The view resolver does a really simple assumption, well someone else does it in the end, the view resolver says: given a view named MySampleView I’ll assume, by default, that the view model will be a type in the same namespace as the view and with the same name as the view with a “Model” suffix, so in this case the view model name will be MySampleViewModel.
Obviously Radical.Windows.Presentation provides a default implementation of the IViewResolver interface, something like this:
public T GetView() where T : DependencyObject
{
var view = this.container.GetService();

if( !this.conventions.ViewHasDataContext( view ) )
{
var viewModelType = this.conventions.ResolveViewModelType( typeof( T ) );
var viewModel = this.container.GetService( viewModelType );

this.conventions.AttachViewToViewModel( view, viewModel );
this.conventions.SetViewDataContext( view, viewModel );

}

return view;
}
Well…what’s going on here?
First of all a couple of notes about involved actors:
  • container is the Inversion of Control container, in this case it is just an IServiceProvider instance and GetService is an extension method that “hides” all the ugliness of type casting;
  • conventions is a really simple component that handles conventions, that the end user can change to satisfy his own needs;
The first thing we do is to grab a reference to the view, given its T type, then we ask to the conventions handler if the view has a “data context” set.
Q: Why we ask it to the conventions handler?
A: Basically the problem is that a DependencyObject does not have a DataContext property, DataContext is exposed by FrameworkElement and FrameworkContentElement that are not in the same inheritance chain so we cannot query just a single base class; This tells me that other controls (such as third party controls) can behave in a different manner and the end user needs to be able to plug his own logic.
The second assumption we do here is: if the resolver view already has a DataContext property set it’s a singleton view and has been already resolved once, so do not do anything else and return the view to the caller.
On the other end if the view is not a singleton or if it is the first time we resolve that view we:
  • ask to the conventions handler, given the view type, to tell us which is the view model type;
  • resolve the view model using the Inversion of Control container;
  • attach the view to the view model…what the hell is this? we’ll see it in a minute;
  • set the DataContext of the view to the resolved view model instance, we use the conventions handler for the reasons explained above;
There are also a couple of other things we do but we’ll let them for another post.
Why do we attach the view to the view model?
Well, this is one of the decisions driven by the simplicity pillar: in every desktop application you have, at one point, to deal with the view, as the following really frequent sample demonstrates:
Dialogs: you need to request, from a view model, to open a dialog to ask something to the user (e.g. choose a file on disk); you’ll try to do everything respecting the pattern, so you send a “ChooseFileRequest” message using your favorite message broker but at one point you realize that you need to give to the dialog instance its own owner, otherwise you start facing really cool behaviors where dialogs are dialogs but are not topmost and cannot be brought on top… :-/
Radical.Windows.Presentation introduce a really simple way to achieve that, just fire your message in the usual way and introduce in the message the concept of “owner”; for example if the calling view model is the designated owner you can write something like this:
var message = new ChooseFileRequest()
{
   Owner = this;
}

this.broker.Broadcast( message );
Now what you can do in the message handler is something like:
var window = message.Owner.FindWindow();
var view = viewResolver.GetView();
view.Owner = window;

view.ShowDialog();
where FindWindow is an extension method provided by the infrastructure whose role is to find the window instance that is hosting the given view model…how? simply using the conventions handler, asking it the current view associated with the view model and reverse walking the visual tree until it finds the Window object.
Easy…isn’t it? Smile
.m

A challenging question…

Why do we need relations (in terms of relational database relations)?
I see only one good reason.
.m

Monday, October 24, 2011

Radical on nuget :-)

Radical.nuget
After a lot of dillydallying, mainly due to laziness, Radical (well a part of it) it is finally arrived on nuget:
http://nuget.org/List/Search?packageType=Packages&searchCategory=All+Categories&searchTerm=Radical&sortOrder=package-download-count&pageSize=10
Cool…but what a pain Smile, I’ve rebuild/reorganized everything 3 times before banging on target.
Some tips for the first time user:
  • First of all read the manual Smile;
  • Get the tools, especially if, like me, you don’t like the console Winking smile;
  • Go and read David Ebbo’s posts, they are a lifesaver and avoid that you bang your head against the wall…as I did Confused smile;
After those 3 things…well breath, breath and breath again…now review some of your code and concepts:
  • nuget packages must be small, when you add a nuget reference all the assemblies found in package will be referenced in the project;
  • Visual Studio will try to add the most suitable reference…what does it mean? imagine that the package has the following structure:
    • Package:
      • net35
        • Radical.dll
        • Radical.Windows.dll
      • net40
        • Radical.Windows.dll
and that the project you are working on targets the .net 4.0 framework, you end up having only the Radical.Windows.dll referenced by the project.
So the solution is to have small packages that depends on other small packages, at first you can think that it is a mess, but in the end you’ll find that handling small packages is far better because lets you handle dependencies and upgrades in a more agile manner;
  • One last, but not least, thing I really like of nuget is a side-effect: basically nuget force you to do a deep use o unit tests, even if you are only using nuget just for your own needs; basically the update process is a process and as all the processes requires a bunch of steps every time you need to upgrade a component, and once you have deployed a failing component you need to update all the stuff once again…a pain, far far better to unit tests everything in order to dramatically reduce the effort of the redeploy;
Happy nugetting Smile with tongue out
.m

Wednesday, October 5, 2011

Monitoring sources for events in a M-V-VM world

My dear colleague Matteo yesterday came up with a question, that per se is fairly easy, imagine a scenario where you have a OuterViewModel that exposes an InnerViewModel and a command, such as:
class InnerViewModel : INotifyPropertyChanged
{
   
}

class OuterViewModel : INotifyPropertyChanged
{
    public OuterViewModel()
    {
        //your own logic to setup the command and the inner view model
    }

    public InnerViewModel Inner{ get; set; }
    public ICommand DoSomething{ get; }
}
Now Matteo wants that, each time a property exposed by the InnerViewModel changes, the command evaluation status is re-evaluated. As we said the solution is simple, just attach an handler to the PropertyChanged event of the InnerViewModel and re-evaluate the command.
So far…so good…with a lot a pollution around Smile
Why pollution?
  1. The ICommand interface does not expose a method to request the command re-evaluation;
  2. You have to remember to attach the event on the inner view model and it is not natural because the focus, during development, is on the command not on the source of the change notification; this is the typical situation where you want a command to react to something that has happened…nothing more;
Radical to the rescue
Let’s se what you can achieve using the Radical framework:
class OuterViewModel : INotifyPropertyChanged
{
    public OuterViewModel()
    {
        //your own logic to setup the inner view model

        this.DoDomething = DelegateCommand.Create()
                   .OnCanExecute( o => return true ) //your own validation logic
                   .OnExecute( o => {  } ) //your own execution logic
                   .AddMonitor( PropertyObserver.ForAllPropertiesOf( this.InnerViewModel );
    }

    public InnerViewModel Inner{ get; set; }
    public ICommand DoSomething{ get; }
}
Or even easier using the brand new extension method:
class OuterViewModel : INotifyPropertyChanged
{
    public OuterViewModel()
    {
        //your own logic to setup the inner view model

        this.DoDomething = DelegateCommand.Create()
                   .OnCanExecute( o => return true ) //your own validation logic
                   .OnExecute( o => {  } ) //your own execution logic
                   .Observe( this.InnerViewModel );
    }

    public InnerViewModel Inner{ get; set; }
    public ICommand DoSomething{ get; }
}
easy peasy lemon squeezy Smile, implementing your own monitors is really straightforward, just implement the IMonitor interface or even easier inherit from the AbstractMonitor/AbstractMonitor base classes.
Side notes:
  • under the hood the DelegateCommand utilizes the weak event pattern;
  • all the presented stuff is available for the full FX, for Silverlight 4 and for the Phone;
Do you want to give it a try? nuget it: Radical on nuget and Radical.Windows on nuget. (Radical contains the observers stuff and Radical.Windows the DelegateCommand)
.m

Saturday, October 1, 2011