Notification pattern
When I have to propagate errors from the domain object to the presentation I usually use exceptions. All errors bubble from bottom to up and then are ready to be published to the UI (managing the catch section). The Notification pattern can be a good alternative. Consider a notification class which contains a list of possible errors (for simplicity I don't consider information messages):
public class Notification
{
private List<Error> _errors;
public Notification()
{
_errors = new List<Error>();
}
public List<Error> Errors
{
get
{
return _errors;
}
}
public bool HasErrors
{
get
{
return (0 != _errors.Count);
}
}
public void Clear()
{
_errors.Clear();
}
public class Error
{
private string _message;
public string Message
{
get { return _message; }
set { _message = value; }
}
public Error() { }
public Error(string message)
{
_message = message;
}
}
}
Then, I could create an interface for all of my domain objects:
public interface IDomainObject
{
Notification Notification { get; }
void Validate();
}
The Validate method is used to validate the domain object depending its constrain rules. For example the Customer class could have two constrains:
public void Validate()
{
if (string.IsNullOrEmpty(_code) || _code.Length != 4)
_notification.Errors.Add(new Notification.Error("The Customer code is not well formatted."));
if (string.IsNullOrEmpty(_lastName))
_notification.Errors.Add(new Notification.Error("The last name must be defined"));
}
Once the validate has collected the list of errors to communicate to the presentation view, I have to find a way to show them in the web page (ASP.NET). I then created a custom validator class containing my error message:
public class NotificationMessageValidator : IValidator
{
private string _errorMessage;
public NotificationMessageValidator()
{
}
public NotificationMessageValidator(string errorMessage)
{
_errorMessage = errorMessage;
}
public string ErrorMessage
{
get
{
return _errorMessage;
}
set
{
_errorMessage = value;
}
}
public bool IsValid
{
get
{
return false;
}
set
{
}
}
public void Validate()
{
}
}
Then, the presenter class can fill the page validator collection:
Customer customer = new Customer(_view.Code, _view.FirstName, _view.LastName);
customer.Validate();
if (customer.Notification.HasErrors)
{
foreach (Notification.Error error in customer.Notification.Errors)
_view.Page.Validators.Add(new NotificationMessageValidator(error.Message));
}
With a simple SummaryValidator inside the page I'll see all error messages shown in my web page. I can see two main advantage vs exceptions:
- I can manage/show more than one error message at a time
- It consumes less system resources