Search code examples
exceptionmessageboxcaliburn.micro

Exception/MessageBox in Calibur.Micro


I start learning Caliburn.Micro and I am little confuse of handling with exception/messange box in view model class.

I found some blogs about, for example:

http://frankmao.com/2010/11/18/handling-messagebox-in-caliburn-micro/

For example some method in view model class which can produce exception.

    public void MethodWichCanProduceEx(string arg1, string arg2 )
    {
        if(arg1==null)
            throw new ArgumentNullException("arg1 is null");
        if (arg2 == null)
            throw new ArgumentNullException("arg2 is null");

        try
        {

        }
        catch (Exception exception)
        {

            throw exception;
            //? show message box MessageBox.Shox(exception.Message)
        }
    }

What is correct handling and showing these exception in view ? It exist any kind of pattern for caliburn.micro?

It possible trace exception as in .NET in text, xml file ?

For example I would like trace exception in xml, text file and in view show only message.box or something message.

Thank for advance, maybe is my question little stupid, sorry I am only learning calibur.micro.


Solution

  • You'll want to always work against abstractions in your view models, in the case of message boxes, you don't want to have to wait for user input when you come to unit test your view models.

    The Frank Mao code you linked to uses a delegate to abstract the implementation of the message box from the view model, but I would use an interface here. You can think of a delegate as an interface with a single method, but the advantage of using an interface in this context is that you can have different methods depending on the type of message you wish to show. For example, you could have a ShowMessageError, ShowMessageWarning, ShowMessageInfo etc.

    So, define a contract for your message box:

    public interface IMessageBox
    {
      void ShowException(Exception exc);
    }
    

    Inject the message box dependency into your view model, e.g. via the constructor

    public class MyViewModel
    {
      private readonly IMessageBox messageBox;
    
      public MyViewModel(IMessageBox messageBox)
      {
        this.messageBox = messageBox;
      }
    
      public void MethodThatCanThrowException()
      {
        try {}
        catch(Exception exc)
        {
          // log the exception here
          ...
          // show message box
          this.messageBox.ShowException(exc);
        }
      }
    }
    

    You can then implement the message box anyway you wish, either using the windows system message box, or nicer still use your own view/viewmodel to display the message, perhaps using the Caliburn.Micro WindowManager.ShowDialog().

    An implementation that uses the windows system message box may look like:

    public class StandardMessageBox : IMessageBox
    {
      public void ShowException(Exception exception)
      {
        MessageBox.Show(exception.ToString(), "Error Occurred");
      }
    }
    

    In production code, you can register StandardMessageBox against the IMessageBox interface in your IoC container.

    In unit test land, you can mock out IMessageBox and have it do nothing, or in the case of methods with a result from the message box, always return a value you wish.

    For logging the exception, I would look at a logging framework such as log4net (http://logging.apache.org/log4net/index.html) or NLog (http://nlog-project.org/)