I've run into the same scenario in the past and I used nullable variables in the background to track which properties actually had manually entered values and which were derived (per my use case) and always returned a default value so there was never an issue with missing values. For example, my StartDate property appeared as:
public System.DateTime StartDate
{
get
{
if (_startDate.HasValue)
return _startDate.Value;
else if (_endDate.HasValue)
return _endDate.Value.Subtract(Duration);
else
return System.DateTime.Today; // Or something else
}
set
{
if (value == null)
_startDate = null;
else
(
_startDate = new System.Nullable<System.DateTime>(value);
if (_endDate.HasValue)
_duration = null; // forces duration to be derived
}
}
}
EndDate would be similar:
public System.DateTime EndDate
{
get
{
if (_endDate.HasValue)
return _endDate.Value;
else
return StartDate.Add(Duration);
}
set
{
if (value == null)
_endDate = null;
else
(
_endDate = new System.Nullable<System.DateTime>(value);
if (_startDate.HasValue)
_duration = null; // forces duration to be derived
}
}
}
And Duration would be:
public System.TimeSpan Duration
{
get
{
if (_duration.HasValue)
return _duration.Value;
else if (_startDate.HasValue) && (_endDate.HasValue)
return _endDate.Value.Subtract(_startDate.Value);
else
return System.TimeSpan.Zero;
}
set
{
if (value == null)
_duration = null;
else
(
_duration = new System.Nullable<System.TimeSpan>(value);
if ((_startDate.HasValue) && (_endDate.HasValue))
_endDate = null; // forces endDate to be derived
}
}
}
This eliminated my need to do any validation except to make sure that the dates were within valid ranges and that the EndDate was always the same or later than the StartDate (and example of which is shown in the book and sample app).
Hope that helps.
You could also do the above with validation rules (including the computation of any two of the fields from the other two). Sometimes you don't have the luxury of tinkering inside the property setter (e.g. code is generated).
The trick in doing this is to avoid getting into some weird infinite loop since the 3 values are interdependent, and to handle the case where no property was changed but someone calls CheckRules() explicitly. Also, you might just have 3 discrete rules and not use the dependencies.
Also, rules don't have to be warnings -- you can have a rule that just does a transformation and always succeeds.
Copyright (c) Marimer LLC