Tuesday, October 26, 2010

Silverlight Cookbook: ViewModels, Coroutines and Binding Conventions

This post is part of a series of blog posts detailing various aspects of the Silverlight Cookbook, an initiative to demonstrate proper design choices for building enterprise-class line-of-business applications with Silverlight (and WPF if you will). It currently consists out of the following parts.

After having covered querying, commanding and the domain model, it is time for discussing some of the Silverlight application details. But before I do that, let's list the components I currently use:

Consider the client part of my reference architecture

clip_image001

Shell

The first essential part of every application is the Shell. It's a placeholder for all UI behavior related to menu bars, error messages, last-chance exception handling and the Master-page equivalent for Silverlight. Originally, I was planning to use the Regions and Views concept such as provided the Composite Application Guidance (CAG) block of Prism. But once I started working with the combination of Caliburn Micro (CM) and the Silverlight Business Navigation project template and added one of the awesome free themes, I never needed something like that anymore. As a nice bonus, the Business Navigation template already handles deep linking and back/forward support for you. And if you're building a Line-of-Business application, check out the new Jetpack theme. It's excellent for exactly that purpose.

If you don't want to use the Business Navigation template, CM offers a complete solution consisting of a Screen class representing the ViewModel of a XAML page or a user control, and a Conductor class that represents the Shell and allows activating and deactivating individual screens. The out-of-the-box conductor only allows having one active screen (aka SDI), but it is quite trivial to support an MDI-style application because the CM design is very extensible. For instance, the Screen class implements a whole bunch of interfaces that allows your ViewModel to hook in its life-cycle. Examples of those interfaces include IActivate, IDeactivate, IGuardClose and IChild. Notice that this approach is based on the ViewModel-first concept. In other words, you are always activating ViewModels where CM will use conventions to figure out which XAML page, XAML fragment or User Control to display.

In the case of the Business Navigation template, the conductor functionality is handled by a Silverlight Frame control. CM provides a FrameAdapter class that makes sure that the above mentioned life-cycle notifications are also applied to ViewModels that are associated with the XAML pages that the Frame control loads. As such CM supports both a ViewModel-first approach as well as View-first.

ViewModels

Obviously, no serious developer will build a Silverlight application without applying the Model-View-ViewModel pattern. Let's start with the code that is involved when loading a view. It's from The CQRS Kitchen demo and represent the ViewModel for a view that is used to search for recipes.

    public class SearchViewModel : Screen

    {

        [Dependency]

        public IApplicationController ApplicationController { get; set; }

 

        [Dependency]

        public IQueryAgent QueryAgent { get; set; }

 

        protected override void OnInitialize()

        {

            MinimumRating = 0;

            PartialDescription = "";

            PartialName = "";

        }

The first thing to notice is the base-class this ViewModel is deriving from. It extends CM's Screen class, which offers a way for raising the INotifyPropertyChange using type-safe expressions instead of using literal strings, and implements all the plumbing needed for hooking into the life-cycle interfaces CM offers. You don't necessarily need to derive your ViewModels from Screen and can implement those interfaces directly, but using the Screen class prevents your ViewModel from becoming too obscure.

The OnInitialize method is one of those life-cycle methods I mentioned before but is not doing anything useful in this particular case other than setting the defaults for the search fields. Notice the use of the NotifyOfPropertyChange method in the property setters below. That's the PropertyChangedBase class in action where Screen is deriving from. It will raise the corresponding NotifyPropertyChanged event, and make sure it is raised from the UI thread, regardless of the thread you called NotifyOfPropertyChange from.

        public string PartialName

        {

            get { return partialName; }

            set

            {

                partialName = value;

                NotifyOfPropertyChange(() => PartialName);

            }

        }

 

        public string PartialDescription

        {

            get { return partialDescription; }

            set

            {

                partialDescription = value;

                NotifyOfPropertyChange(() => PartialDescription);

            }

        }

 

        public double MinimumRating

        {

            get { return minimumRating; }

            set

            {

                minimumRating = value;

                NotifyOfPropertyChange(() => MinimumRating);

            }

        }

The code also shows some dependencies this particular ViewModel has on other application-specific services. In the reference architecture, the ApplicationController is responsible for navigating to other views or dialog windows and knows the URLs of their XAML files. This way I can verify the navigation behavior of the ViewModel without the need to know anything about the actual URL or the required query parameters.

In this demo application I use Unity to handle dependency injection, but CM can be extended to use any IoC framework by overriding the appropriate methods in the class that inherits from the Bootstrapper class:

    public class ClientBootstrapper : Bootstrapper<ShellViewModel>

    {

        private readonly IUnityContainer container = new UnityContainer();

 

        protected override void Configure()

        {

// Setting up the Unity container left out for brevity...

        }

 

        protected override object GetInstance(Type service, string key)

        {

            if (service == null)

            {

                service = GetViewModelTypeNameFromKey(key);

                key = "";

            }

 

            return container.Resolve(service, key);

        }

 

        private static Type GetViewModelTypeNameFromKey(string key)

        {

            var viewModelType = from type in typeof(ShellViewModel).Assembly.GetTypes()

                                where type.Name.Equals(key, StringComparison.InvariantCultureIgnoreCase)

                                select type;

 

            return viewModelType.SingleOrDefault();

        }

 

        protected override IEnumerable<object> GetAllInstances(Type service)

        {

            return container.ResolveAll(service);

        }

 

        protected override void BuildUp(object instance)

        {

            container.BuildUp(instance.GetType(), instance);

        }

    }

Coroutines

So let's look at the code that searches for existing recipes.

        public IEnumerable<IResult> FindRecipes()

        {

            var coroutine = new FindRecipesCoroutine

            {

                PartialName = partialName,

                PartialDescription = partialDescription,

                MinimumRating = (int)(minimumRating * MaxRating)

            };

 

            yield return coroutine;

 

            Recipes = coroutine.Recipes;

        }

It should look rather unconventional, especially the usage of the yield keyword and the reference to the IResult interface in the return type declaration. This interface is part of CM and defined as:

    public interface IResult

    {

        void Execute(ActionExecutionContext context);

 

        event EventHandler<ResultCompletionEventArgs> Completed;

    }

You can easily deduce from this definition that a class implementing this interface is supposed to do something upon calling Execute and should notify the caller when that is finished. In essence, this is an asynchronous version of the Command Pattern, but most people refer to it as a Coroutine. CM will assume that all ViewModel methods that return an IEnumerable of IResult are doing asynchronous work and will ensure that the Execute method of a coroutine is not executed until the previous one has completed. The compiler will do the rest. Why?

Well, this is probably the first time I've actually found good use of the yield keyword. Because what happens here is that the compiler will generate a hidden class for the FindRecipes method. This class implements IEnumerable and breaks the method body into two steps that are executing sequentially as part of each IEnumerable.Next call. As such, the first step will construct the FindRecipesCoroutine class and return it. CM will then invoke its Execute method and wait until its Completed event has completed. Only then, it will continue enumerating and cause the code following the yield to execute. By returning multiple coroutines you can create a kind of mini-workflow because the compiler and CM will ensure everything is executed in the right order. That is awesome, isn't it!?

The coroutine itself is not that complex.

    public class FindRecipesCoroutine : SimpleCoroutine

    {

        [Dependency]

        public IQueryAgent QueryAgent { get; set; }

 

        public string PartialName { get; set; }

 

        public string PartialDescription { get; set; }

 

        public int MinimumRating { get; set; }

 

        public IEnumerable<Recipe> Recipes { get; internal set; }

 

        protected override void OnExecute()

        {

            QueryAgent.FindRecipes(MinimumRating, PartialName, PartialDescription,

                recipes =>

                {

                    Recipes = recipes.ToArray();

                    OnComplete();

                });

        }

    }

It's just a thin wrapper that calls a facade hiding the complexities (ugliness) of using WCF Data Services. And since we can rely on CM to inject any dependencies using the configure IoC container, even this class is easily testable. Notice the SimpleCoroutine template class. It's something I created myself to get rid of the repeating code required for declaring and raising the Completed event. The CQRS Kitchen demo also includes a ComplexCoroutine that allows using multiple yield return statements in the OnExecute method to wrap mini-workflows into a coroutine.

In this case, the Recipes property simply exposes the Recipe objects that were generated by the Add Service Reference context menu option of Visual Studio. Because those classes implement INotifyPropertyChanged, In most cases that is sufficient for all kinds of tracking purposes. However, sometimes you have to add some derived properties that are specific to the ViewModel. In usually extend the generated class and add whatever I need for my particular situation and postfix that class with Model. That signifies the fact that I see those classes a part of my ViewModel.

Binding Conventions

You may have noticed the lack of any logic that handles or returns instances of ICommand as you'll find in many other MVVM examples. In fact, I never explained how the XAML view gets attached to the ViewModel, and where this ViewModel instance is created in the first place. This is all part of CM's convention-based binding.

In short, regardless of whether you go for View-first or ViewModel-first, CM will ensure that the ViewModel instance is set as the DataContext of the view, that its dependencies are injected, and that the implemented lifecycle interfaces are called. Additionally, CM will automatically bind UI controls to the ViewModel properties based on the control's name. The specific control property and UI event part of that binding is defined by CM's ConventionManager class, and can be easily changed. Just check out the ClientBootstrapper on CodePlex.

The same applies to invoking methods on the ViewModel. By default, CM will relate buttons with a particular name to the corresponding equally named method (which may or may not use coroutines). It even supports passing the values of other UI elements as the parameters of that method, again by matching their names. And if your ViewModel has a boolean property or method with the same name, but prefixed with Can, then CM will use that to dynamically disable and enable the corresponding button. Morever, using event triggers, you can hook up methods to virtually any UI control event available.

Rob Eisenberg, the author of CM, has written some pretty elaborate articles demonstrating the power of his convention-based binding. Read the introduction first and then continue with the stuff about the actions.

Miscellaneous goodies

For a long while I have been wishing Patterns & Practices would develop a version of the Policy Injection Application Block suitable for Silverlight. But recently, a community member came up with a CM extension that looks similar to the Action Filters concept in ASP.NET MVC. With that you can apply attributes to your ViewModel properties and methods like [Async], [Rescue], [SetBusy], [Dependencies] or anything else you can come up with yourself. The CQRS Kitchen is not using this yet, but that’s one of things I plan to the next weeks.

Another little gem for which I'm quite happy CM provided a solution, is its IObservableCollection<T> interface and the corresponding BindableCollection<T>. Now it's finally possible to expose a collection that implements INotifyCollectionChanged, without exposing the actual collection class itself. I'm one of those guys that tries to restrict any collection properties to Ienumerable<T>, so having IObservableCollection is a great life saver. But it gets better. The BindableCollection will automatically raise its events from the UI thread, even if you add or remove items from a background thread.

Well, this post has ended up being a bit longer than I expected, and I’m not done yet, so keep checking back once in a while. Topics I have in mind include at least UI validation, the service agent and event aggregation.

Tuesday, October 19, 2010

ALM Practices Part 12: Reducing Technical Debt

What is it?

Technical Debt is every change to your code base that does not comply with the usual level of quality your team has agreed upon. Since this level of quality has been introduced to guarantee a healthy code base throughout the life time of the system, introducing technical debt essentially reduces your team’s ability to quickly add new functionality or to easily find bugs. Examples

  • Changing the preferred design for a recurring problem half-way the project without changing the code that was built with the previous design choice. For instance, switching from a UI pattern like Model-View-Presenter to Model-View-ViewModel;
  • Copying and pasting code that is mostly the same; a violation of the Don’t Repeat Yourself principle (DRY);
  • Choosing a quick and dirty solution to get something done under pressure;
  • Not introducing a unit test where you should have;
  • Introducing unnecessary complexity were a simple solution would have been sufficient, simply because you try to prepare for the future (which you can’t really);

Why would you do it?

Because technical debt is going to slow you down at one point or another. Whether it is a bug you need to fix at multiple places, a confused new developer that has no clue which solution to use, or incorrectly chosen responsibilities, it will prevent you from moving on. New functionality which should be easy to add, suddenly becomes very difficult to add, either because of a complex design or because you are afraid to break other parts of the system. In addition to that, most systems include a lot of repetitive work or recurring problems. At least consider replacing this with a better solution so that you don’t end up with repetitive maintenance.

What’s the minimum you need to do?

  • Create a shared list of items referring to specific issues contributing to the technical debt.
  • Add items to that list during reviews, during construction, or when you encounter something you don’t have time to fix right now.
  • Allow anyone in the team to add items to that list.
  • Prioritize the items on the list so that the ones causing the most amount of pain are at the top of the list.
  • Make sure you account for the costs and risks involved in removing the technical debt. Not everything is worth the trouble and whether or not it does depends largely on the specific project and customer environment.
  • Whenever you can, try to combine the current activity with small improvements that reduce technical debt.
  • Listen to your gut feeling when you have doubts about the desired quality of your code base. Consult a team member or a colleague if you can’t find a better solution yourself.
  • Practice Test Driven Development or another automated testing style to maintain a safety net when reducing the technical debt.
What’s the usual thing to do?
  • When you start a new project, it is not uncommon to introduce a bit of technical debt in the first one or two sprints so that you can release your first version quickly. However, make sure you schedule tasks to fix that in the next sprints.
  • Schedule major redesigns required for reducing technical debt as part of your planning process. For instance, if you’re practicing Scrum, add the technical debt as technical user stories and explain why it this is needed.
  • Attach a large physical sheet on the wall listing the top 5 items. For obvious reasons this list is called the Wall of Pain.
  • Organize regular (like monthly) brown paper sessions with the entire team to review a part of the code-base to see if the system is still in a healthy state.
  • Apply Peer Reviews or Pair Programming to detect and remove technical debt as early as possible.

Wednesday, October 13, 2010

My Silverlight 4 Reference Architecture: The Domain Model

The Domain Model is roughly designed according to the DDD principles where cross-aggregate logic is handled by the command handlers instead of the more traditional domain services. One thing that I changed after I attended Greg Young's DDD/CQRS training is that I no longer allow my domain entities to enter an invalid state. So rather than having some kind of interceptor that does the validation as part of the persistency layer, all validation happens while making the changes:

    public class Agreement : VersionedEntity

    {

        public virtual string Title

        {

            get { return title; }

            set

            {

                EnsureChangesAreAllowed();

 

                if (string.IsNullOrEmpty(value))

                {

                    throw new RuleViolationException("A new agreement requires at least a title.");

                }

 

                title = value;

            }

        }

    }

I’m currently using this approach in a client project, and admit I still have to build up more experience to see if you get away with this approach. Up to now it works for me, but I wouldn’t be surprised if I run into an exception (don’t we all?).

As a side note, the VersionedEntity you see up here is just a base class including an Id and Version property for concurrency detection. Since most systems have some entities that rarely change (a.k.a. reference data), no version detection is necessary. Hence the difference between the Entity and VersionedEntity base classes.

As mentioned before, I use NHibernate accompanied by LINQ and Fluent NHibernate, but I still use the Repository pattern to hide all the LINQ stuff that goes on inside the repositories. The current request-specific ISession is tracked by a session manager class that the Command Handlers and Service Actions will create as part of their execution.

I know that I, at least for a while, advocated that all repository interfaces should expose IQueryable<T> so that you can easily execute LINQ queries from your higher layers. But I've found that testing that your code has created the proper LINQ query is virtually impossible, and now stick to exposing explicit well-named operations only.

    public interface IAgreementRepository : IRepository<Agreement>

    {

        Agreement Get(long id, long version);

        void Add(Agreement agreement);

        bool ExistsForCpiCaseNumber(string cpiCaseNumber);

        IEnumerable<AgreementValidityInCountry> Find
           
(AgreementValidityPerCountrySpecification
specification);

    }

And now that I’m discussing repositories anyway, one recurring design issue is whether to allow an entity to access any repositories or other services. My personal opinion is a pragmatic one: yes, as long as the related dependency injection doesn’t affect the performance significantly (and yes, you need to measure that). If you don’t allow this, you may very well end up with an anemic domain model.

Another aspect of my domain model approach is that to prevent any unrelated logic creeping in a command handler just because a change to an aggregate root affects another aggregate, I use Udi's approach to raise Domain Events that are handled by Event Handlers.

   public static class DomainEvents

   {

      [ThreadStatic]

      private static List<Delegate> actions;

 

      public static void Register <T>(Action<T> callback) where T : IDomainEvent

      {

         if (actions == null)

         {

            actions = new List<Delegate>();

         }

         actions.Add(callback);

      }

 

      public static void ClearCallbacks()

      {

         actions = null;

      }

 

      public static void Raise <T>(T args) where T : IDomainEvent

      {

         if (actions != null)

         {

            foreach (Delegate action in actions)

            {

               if (action is Action<T>)

               {

                  ((Action<T>) action)(args);

               }

            }

         }

      }

   }

If you want to subscribe to a particular event, do this:

DomainEvents.Register<StockCorrectedEvent>(StockCorrectedHandler.Handle);

Where the method reference resolves to an Event Handler class that implements this interface.

   public interface IHandle<T> where T : IDomainEvent

   {

      void Handle(T args);

   }

To raise a domain event from inside your domain entity, simply call the Raise method like this:

DomainEvents.Raise(new StockCorrectedEvent(this, location, originalAmount, newAmount));

Next time I'll dive into the details of my Silverlight client application and my usage of Model-View-ViewModel and the Caliburn Micro framework.