tags:

views:

7

answers:

0

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.