Dear ladies and sirs. Observe the following simple class and its respective XAML:
namespace NetworkCatcher.Entities.Server.Cfg
{
public sealed class Settings : ISupportInitialize
{
private static readonly TimeSpan MinCrashRecoveryDuration = TimeSpan.FromSeconds(15);
private static readonly TimeSpan MaxCrashRecoveryDuration = TimeSpan.FromMinutes(10);
private static readonly TimeSpan MinFlushTimerInterval = TimeSpan.FromSeconds(5);
private static readonly TimeSpan MaxFlushTimerInterval = TimeSpan.FromMinutes(5);
private const int MinBulkSize = 6;
private const int MaxBulkSize = 10000;
[TypeConverter(typeof(CompactTimeSpanConverter))]
public TimeSpan CrashRecoveryDuration { get; set; }
public int BulkSize { get; set; }
[TypeConverter(typeof(CompactTimeSpanConverter))]
public TimeSpan FlushTimerInterval { get; set; }
void ISupportInitialize.BeginInit()
{
}
void ISupportInitialize.EndInit()
{
CrashRecoveryDuration = Utils.Max(MinCrashRecoveryDuration, Utils.Min(MaxCrashRecoveryDuration, CrashRecoveryDuration));
FlushTimerInterval = Utils.Max(MinFlushTimerInterval, Utils.Min(MaxFlushTimerInterval, FlushTimerInterval));
BulkSize = Math.Max(MinBulkSize, Math.Min(MaxBulkSize, BulkSize));
}
}
}
<cfg:Settings xmlns:cfg="clr-namespace:NetworkCatcher.Entities.Server.Cfg;assembly=NC.Entities.Server"
CrashRecoveryDuration="1m"
BulkSize="6"
FlushTimerInterval="5s" />
What really annoys me is how I make sure the values are in range. What I really would like is to use custom attributes to make this check declarative, something like that:
namespace NetworkCatcher.Entities.Server.Cfg
{
public sealed class Settings
{
[Min("15s"), Max("10m")]
[TypeConverter(typeof(CompactTimeSpanConverter))]
public TimeSpan CrashRecoveryDuration { get; set; }
[Min(6), Max(10000)]
public int BulkSize { get; set; }
[Min("5s"), Max("5m")]
[TypeConverter(typeof(CompactTimeSpanConverter))]
public TimeSpan FlushTimerInterval { get; set; }
}
}
Where CompactTimeSpanConverter is a type converter allowing me to specify TimeSpan like 5s or 10m, which mean 5 seconds or 10 minutes respectively. Now, the type converter thing is easy and already done, the question is how to implement Min and Max custom attributes.
The solution I see is to have a base class implementing ISupportInitialize, where it would discover the attributes and make the necessary validations. But, I would like to know if there is a XAML focus to make it work with less effort.
Thanks.
EDIT
Forgot to mention. I would like the solution to stay confined within the System.Xaml assembly. Maximum, WindowsBase, but surely not PresentationCore or PresentationFramework.