Click here to Skip to main content
15,884,041 members
Articles / Desktop Programming / WPF

Catel - Part 4 of n: Unit testing with Catel

Rate me:
Please Sign up or sign in to vote.
4.55/5 (10 votes)
28 Jan 2011CPOL11 min read 48.9K   572   11  
This article explains how to write unit tests for MVVM using Catel.
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="ViewModelBase.cs" company="Catel development team">
//   Copyright (c) 2008 - 2011 Catel development team. All rights reserved.
// </copyright>
// <summary>
//   View model base for MVVM implementations. This class is based on the <see cref="DataObjectBase" />, and supports all
//   common interfaces used by WPF.
// </summary>
// --------------------------------------------------------------------------------------------------------------------

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Configuration;
using Catel.MVVM.Services;
using Catel.Windows.Properties;
using log4net;
using log4net.Core;
using Microsoft.Practices.Unity;

#if !SILVERLIGHT
using Microsoft.Practices.Unity.Configuration;
#endif

namespace Catel.MVVM
{
    /// <summary>
    /// View model base for MVVM implementations. This class is based on the <see cref="DataObjectBase"/>, and supports all
    /// common interfaces.
    /// </summary>
    /// <remarks>
#if SILVERLIGHT
    /// This class registers the Silverlight-specific view model services.
#else
    /// This class registers the WPF-specific view model services.
#endif
    /// </remarks>
    public abstract class ViewModelBase : ViewModelBaseWithoutServices
    {
        #region Constructor & destructor
        /// <summary>
        /// Initializes a new instance of the <see cref="ViewModelBase"/> class with support for <see cref="IEditableObject"/>.
        /// </summary>
        protected ViewModelBase() { }

        /// <summary>
        /// Initializes a new instance of the <see cref="ViewModelBase"/> class.
        /// </summary>
        /// <param name="supportIEditableObject">if set to <c>true</c>, the view model will natively support models that
        /// implement the <see cref="IEditableObject"/> interface.</param>
        protected ViewModelBase(bool supportIEditableObject)
            : base(supportIEditableObject) { }

        /// <summary>
        /// Initializes a new instance of the <see cref="ViewModelBase"/> class.
        /// </summary>
        /// <param name="supportIEditableObject">if set to <c>true</c>, the view model will natively support models that
        /// implement the <see cref="IEditableObject"/> interface.</param>
        /// <param name="ignoreMultipleModelsWarning">if set to <c>true</c>, the warning when using multiple models is ignored.</param>
        /// <exception cref="ModelNotRegisteredException">when a mapped model is not registered.</exception>
        /// <exception cref="PropertyNotFoundInModelException">when a mapped model property is not found.</exception>
        protected ViewModelBase(bool supportIEditableObject, bool ignoreMultipleModelsWarning)
            : base(supportIEditableObject, ignoreMultipleModelsWarning) { }

        /// <summary>
        /// Initializes a new instance of the <see cref="ViewModelBase"/> class.
        /// <para/>
        /// This constructor allows services to be injected. When <param name="services"/> contains any elements, the
        /// <see cref="RegisterViewModelServices"/> method is not invoked.
        /// </summary>
        /// <param name="services">Dictionary of services to register.</param>
        /// <exception cref="ModelNotRegisteredException">when a mapped model is not registered.</exception>
        /// <exception cref="PropertyNotFoundInModelException">when a mapped model property is not found.</exception>
        protected ViewModelBase(Dictionary<Type, object> services)
            : base(services) { }

        /// <summary>
        /// Initializes a new instance of the <see cref="ViewModelBase"/> class.
        /// <para/>
        /// This constructor allows services to be injected. When <param name="services"/> contains any elements, the
        /// <see cref="RegisterViewModelServices"/> method is not invoked.
        /// </summary>
        /// <param name="services">Dictionary of services to register.</param>
        /// <param name="supportIEditableObject">if set to <c>true</c>, the view model will natively support models that
        /// implement the <see cref="IEditableObject"/> interface.</param>
        /// <exception cref="ModelNotRegisteredException">when a mapped model is not registered.</exception>
        /// <exception cref="PropertyNotFoundInModelException">when a mapped model property is not found.</exception>
        protected ViewModelBase(Dictionary<Type, object> services, bool supportIEditableObject)
            : base(services, supportIEditableObject) { }

        /// <summary>
        /// Initializes a new instance of the <see cref="ViewModelBase"/> class.
        /// <para />
        /// This constructor allows services to be injected. When <param name="services"/> contains any elements, the
        /// <see cref="RegisterViewModelServices"/> method is not invoked.
        /// </summary>
        /// <param name="services">Dictionary of services to register.</param>
        /// <param name="supportIEditableObject">if set to <c>true</c>, the view model will natively support models that
        /// implement the <see cref="IEditableObject"/> interface.</param>
        /// <param name="ignoreMultipleModelsWarning">if set to <c>true</c>, the warning when using multiple models is ignored.</param>
        /// <exception cref="ModelNotRegisteredException">when a mapped model is not registered.</exception>
        /// <exception cref="PropertyNotFoundInModelException">when a mapped model property is not found.</exception>
        protected ViewModelBase(Dictionary<Type, object> services, bool supportIEditableObject, bool ignoreMultipleModelsWarning)
            : base(services, supportIEditableObject, ignoreMultipleModelsWarning) { }
        #endregion

        #region Methods
        /// <summary>
        /// Registers the known view model services.
        /// </summary>
        /// <param name="container">The IoC container.</param>
        protected override void RegisterViewModelServices(IUnityContainer container)
        {
            // Logger already created, not IoC required
            ViewModelServiceManager.Add(typeof(ILogger), Log);

            try
            {
                Log.Debug(TraceMessages.RegisteringDefaultServiceImplementationsForIoCContainer);

                container.RegisterType<IOpenFileService, OpenFileService>()
                    .RegisterType<ISaveFileService, SaveFileService>()
                    .RegisterType<IMessageService, MessageService>()
#if !SILVERLIGHT
                    .RegisterType<IPleaseWaitService, PleaseWaitService>()
#endif
                    .RegisterType<IUIVisualizerService, UIVisualizerService>();

                Log.Debug(TraceMessages.RegisteredDefaultServiceImplementationsForIoCContainer);

#if !SILVERLIGHT
                // Load from config, overrides defaults
                UnityConfigurationSection section = (UnityConfigurationSection)ConfigurationManager.GetSection("unity");
                if ((section != null) && (section.Containers.Count > 0))
                {
                    Log.Debug(TraceMessages.ConfiguringIoCContainerViaConfigurationFile);

                    section.Configure(container);

                    Log.Debug(TraceMessages.ConfiguredIoCContainerViaConfigurationFile);
                }
#endif
            }
            catch (Exception ex)
            {
                Log.Error(ex, TraceMessages.FailedToConfigureIoCContainer);

                throw new Exception(Exceptions.FailedToConfigureIoCContainer, ex);
            }

            ViewModelServiceManager.Add(typeof(IOpenFileService), container.Resolve<IOpenFileService>());
            ViewModelServiceManager.Add(typeof(ISaveFileService), container.Resolve<ISaveFileService>());
            ViewModelServiceManager.Add(typeof(IMessageService), container.Resolve<IMessageService>());
            ViewModelServiceManager.Add(typeof(IPleaseWaitService), container.Resolve<IPleaseWaitService>());
            ViewModelServiceManager.Add(typeof(IUIVisualizerService), container.Resolve<IUIVisualizerService>());
        }
        #endregion
    }
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer
Netherlands Netherlands
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions