WPF + MVVM + Exception Handling Application Block

Topics: Exception Handling Application Block
Jul 15, 2011 at 12:39 PM

I have WPF application MVVM (prism 4) and would like to use the Exception handling block on the main ViewModel but the exceptions raised on the sub ViewModels would not call my Exception Handler. Using the service locator on the sub ViewModels would propagate the exception to my exception handler. Any exception raised in CustomerViewModel, AllCustomersViewModel, and  CustomCustomerViewModel would not call my custom handler.

using Microsoft.Practices.EnterpriseLibrary.Common.Configuration;
using Microsoft.Practices.EnterpriseLibrary.ExceptionHandling;

namespace DemoApp.ViewModel
{
    /// <summary>
    /// The ViewModel for the application's main window.
    /// </summary>
    public class MainWindowViewModel : WorkspaceViewModel
    {  ReadOnlyCollection<CommandViewModel> _commands;
/// <summary>
        /// Returns a read-only list of commands 
        /// that the UI can display and execute.
        /// </summary>
        public ReadOnlyCollection<CommandViewModel> Commands
        {
            get
            {
                if (_commands == null)
                {
                    List<CommandViewModel> cmds = this.CreateCommands();
                    _commands = new ReadOnlyCollection<CommandViewModel>(cmds);
                }
                return _commands;
            }
        }
List<CommandViewModel> CreateCommands()
        {
            return new List<CommandViewModel>
                       {
                           new CommandViewModel(
                               Strings.MainWindowViewModel_Command_ViewAllCustomers,
                               new RelayCommand(param => this.ShowAllCustomers())),
 
                           new CommandViewModel(
                               Strings.MainWindowViewModel_Command_CreateNewCustomer,
                               new RelayCommand(param => this.CreateNewCustomer())),
 
                           new CommandViewModel(
                                   Strings.MainWindowViewModel_Command_ViewMyCustomerView,
                                   new RelayCommand(param => this.ShowMyCustomCustomerView()))
                       };
        }
 void CreateNewCustomer()
        {
            EnterpriseLibraryContainer.Current.GetInstance<ExceptionManager>().Process(() =>
                                           {
                                               var newCustomer = Customer.CreateNewCustomer();
                                               var workspace = new CustomerViewModel(newCustomer,_customerRepository);
                                               Workspaces.Add(workspace);
                                               SetActiveWorkspace(workspace);
                                           }, "MainPolicy");
        }
 
        void ShowAllCustomers()
        {
            EnterpriseLibraryContainer.Current.GetInstance<ExceptionManager>().Process(() =>
                                      {
                                          AllCustomersViewModel workspace =
                                              this.Workspaces.FirstOrDefault(vm => vm is AllCustomersViewModel)
                                              as AllCustomersViewModel;
 
                                          if (workspace == null)
                                          {
                                              workspace = new AllCustomersViewModel(_customerRepository);
                                              this.Workspaces.Add(workspace);
                                          }
 
                                          this.SetActiveWorkspace(workspace);
                                      }, "MainPolicy");
        }
 
        void ShowMyCustomCustomerView()
        {
            EnterpriseLibraryContainer.Current.GetInstance<ExceptionManager>().Process(() =>
                                           {
                                               Customer newCustomer = Customer.CreateNewCustomer();
                                               CustomCustomerViewModel workspace =
                                                   new CustomCustomerViewModel(newCustomer,
                                                                               _customerRepository);
                                               this.Workspaces.Add(workspace);
                                               this.SetActiveWorkspace(workspace);
                                           }, "MainPolicy");
        }

}
<?xml version="1.0"?>
<configuration>
    <configSections>
        <section name="exceptionHandling" type="Microsoft.Practices.EnterpriseLibrary.ExceptionHandling.Configuration.ExceptionHandlingSettings, Microsoft.Practices.EnterpriseLibrary.ExceptionHandling, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" requirePermission="true"/>
    </configSections>
    <exceptionHandling>
        <exceptionPolicies>
            <add name="MainPolicy">
                <exceptionTypes>
                    <add name="All Exceptions" type="System.Exception, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" postHandlingAction="None">
                        <exceptionHandlers>
                            <add type="DemoApp.MainExceptionHandler, DemoApp, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" name="MainExceptionHandler"/>
                        </exceptionHandlers>
                    </add>
                </exceptionTypes>
            </add>
        </exceptionPolicies>
    </exceptionHandling>
<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/></startup></configuration>
using Microsoft.Practices.EnterpriseLibrary.Common.Configuration;
using Microsoft.Practices.EnterpriseLibrary.ExceptionHandling;
using Microsoft.Practices.EnterpriseLibrary.ExceptionHandling.Configuration;

namespace DemoApp
{
     [ConfigurationElementType(typeof(CustomHandlerData))]
    public class MainExceptionHandler : IExceptionHandler
    {
         public MainExceptionHandler(NameValueCollection ignore)
         {
         }
        public Exception HandleException(Exception exception, Guid handlingInstanceId)
        {
            MessageBox.Show(exception.Message, "MainExceptionHandler",MessageBoxButton.OK,MessageBoxImage.Error);
            return exception;
        }
    }
}

Jul 18, 2011 at 6:06 AM

Hi,

Unfortunately, ExceptionManager.Process() only works per method not per object. If you want to handle exception thrown across the object, you can use the Exception Handling Handler of Policy Injection Application Block to achieve this.

 

Noel Angelo Bolasoc
Global Technologies and Solutions
Avanade, Inc.
entlib.support@avanade.com