M
Marc Gravell
Just yet another viewpoint...
Validation in the setter is perfect for things that can *never* be
valid, i.e. invalid format, out-of-range, too large, etc. However, it
can get tricky if your business rules cross-reference each other. The
classic example is the DateTimePicker, where Min / Max / Value fight
with eachother; the issue is that you place a dependency on the caller
both setting the right properties *and* setting them in the right
order - which can easily require a 3rd intermediary state.
In such cases, a more explicit Validate() method is useful, but I
agree that this generally belongs to the business entity itself
(unless it is a proxy, in which case all bets are off).
A useful model here is IDataErrorInfo; for starters, if you implement
this it will *automatically* display the messages to the user in some
controls (DataGridView, for example) via an error blob. And it isn't
hard to hook regular bindings to it as well (a bit more manual,
though; and note you need to use the indexer-variant). But more
importantly: it provides a simple method your data-layer can query:
IDataErrorInfo errObj = obj as IDataErrorInfo;
string errMsg;
if(errObj != null && !string.IsNullOrEmpty(errMsg =
errObj.Error)) {
throw new DataException(errMsg);
}
Although any similar "are you happy with yourself?" method would
suffice ;-p
(but is nice to be able to use the same code at both UI and DAL,
without having to do anything special)
Marc
Validation in the setter is perfect for things that can *never* be
valid, i.e. invalid format, out-of-range, too large, etc. However, it
can get tricky if your business rules cross-reference each other. The
classic example is the DateTimePicker, where Min / Max / Value fight
with eachother; the issue is that you place a dependency on the caller
both setting the right properties *and* setting them in the right
order - which can easily require a 3rd intermediary state.
In such cases, a more explicit Validate() method is useful, but I
agree that this generally belongs to the business entity itself
(unless it is a proxy, in which case all bets are off).
A useful model here is IDataErrorInfo; for starters, if you implement
this it will *automatically* display the messages to the user in some
controls (DataGridView, for example) via an error blob. And it isn't
hard to hook regular bindings to it as well (a bit more manual,
though; and note you need to use the indexer-variant). But more
importantly: it provides a simple method your data-layer can query:
IDataErrorInfo errObj = obj as IDataErrorInfo;
string errMsg;
if(errObj != null && !string.IsNullOrEmpty(errMsg =
errObj.Error)) {
throw new DataException(errMsg);
}
Although any similar "are you happy with yourself?" method would
suffice ;-p
(but is nice to be able to use the same code at both UI and DAL,
without having to do anything special)
Marc