I have a custom collection that I am adding a ValidateItem event to. This ValidateItem event will be called whenever an item is added to or updated in the custom collection.
I want to allow derived classes to be able to subscribe to the event and determine their own logic for whether or not an item is "valid" and potentially prohibit it being added to the collection if it is "invalid".
But I am trying to figure out how to let the caller to the event know what is going on and how to pass the information about what is going on back.
My custom eventargs inherit from CancelEventArgs so I have the ability to pass the Cancel bit back to the caller using that. But I have never seen any cases where error information (error codes, messages, etc) gets passed back in this manner, so I'm wondering if this might not be the best approach.
Should I just add any error data that I wish to pass back to my Custom eventargs class, are there good reasons for or against this? or are there other, better ways to accomplish this?
Here is my eventargs class:
public delegate void ItemValidationEventHandler(object sender, ItemValidationEventArgs e);
public class ItemValidationEventArgs : CancelEventArgs
{
public ItemValidationEventArgs(object item, ObjectAction state, EventArgs e)
{
Item = item;
State = state;
EventArgs = e;
}
public ItemValidationEventArgs(object item, ObjectAction state) : this(item, state, new EventArgs())
{
}
public ItemValidationEventArgs() : this(null, ObjectAction.None, new EventArgs())
{
}
// is there a better way to pass this info?
public string ErrorMessage {get; set;}
public int ErrorNumber {get;set;}
public object Item { get; private set; }
public ObjectAction State { get; private set; }
public EventArgs EventArgs { get; private set; }
}
UPDATE: I suppose another other option would be to use something like this:
virtual bool Validate(object item, ObjectAction action, out string errorMessage)
method in the derived classes. Though I tend to prefer avoiding out parameters...
If anyone has any ideas on the pros and cons of each approach I'd love to hear em!
Thanks, Max
Using events for this is probably not the best design approach.
Since it is an inheriting class that would be overriding this behavior, the method should be marked as protected and virtual:
protected virtual bool Validate(object item);
I too do not like using out
on parameters, so following your initial instincts to use EventArgs
, you should probably create a class to encapsulate the results of your validation.
Example:
class ValidationResult
{
public string ResultMessage{get;set;}
public bool IsValid {get;set;}
}
Your method would then be:
protected virtual ValidationResult Validate(object item)
{
ValidationResult result = new ValidationResult();
// validate and set results values accordingly
return result;
}
The pros and cons of using this over events are that events are intended to be used when you want to publish an action or information to multiple subscribers. The subscribers are classes that you know nothing about. You do not care who they are or what they do. They should never really pass information back to the notifying class either. They should just process the event information given to them.
In your instance, your inherited class is your only subscriber. On top of that you want to be able pass useful information back to the parent class. Inheritance fits this desired behavior much better, and also allows you to easily implement different types of validation class. With events, you would have to keep typing code to attach event handlers over and over again (very ugly IMO).