Хотя BindingList<T>
и ObservableCollection<T>
предоставляют механизмы для обнаружения изменений в списке, они не поддерживают механизмы для обнаружения/перехвата изменений. до они происходят.Мнение: перехват изменений в списках/коллекциях
Я пишу пару интерфейсов для поддержки этого, но я хочу, чтобы ваше мнение было холст.
Вариант 1: Списки поднимают события для каждого типа действия
Здесь потребители могут писать код, как это:
public class Order : Entity
{
public Order()
{
this.OrderItems = new List<OrderItem>();
this.OrderItems.InsertingItem += new ListChangingEventHandler<OrderItem>(OrderItems_InsertingItem);
this.OrderItems.SettingItem += new ListChangingEventHandler<OrderItem>(OrderItems_SettingItem);
this.OrderItems.RemovingItem += new ListChangingEventHandler<OrderItem>(OrderItems_RemovingItem);
}
virtual public List<OrderItem> OrderItems { get; internal set; }
void OrderItems_InsertingItem(object sender, IOperationEventArgs<OrderItem> e)
{
if (!validationPasses)
{
e.Cancel = true;
return;
}
e.Item.Parent = this;
}
void OrderItems_SettingItem(object sender, IOperationEventArgs<OrderItem> e)
{
if (!validationPasses)
{
e.Cancel = true;
return;
}
e.Item.Parent = this;
}
void OrderItems_RemovingItem(object sender, IOperationEventArgs<OrderItem> e)
{
if (!validationPasses)
{
e.Cancel = true;
return;
}
e.Item.Parent = null;
}
}
Вариант 2: Списки поднять одно событие, и действие определяется из события args
Здесь потребители могут написать такой код:
public class Order : Entity
{
public Order()
{
this.OrderItems = new List<OrderItem>();
this.OrderItems.ListChanging += new ListChangingEventHandler<OrderItem>(OrderItems_ListChanging);
}
virtual public List<OrderItem> OrderItems { get; internal set; }
void OrderItems_ListChanging(object sender, IOperationEventArgs<OrderItem> e)
{
switch (e.Action)
{
case ListChangingType.Inserting:
case ListChangingType.Setting:
if (validationPasses)
{
e.Item.Parent = this;
}
else
{
e.Cancel = true;
}
break;
case ListChangingType.Removing:
if (validationPasses)
{
e.Item.Parent = null;
}
else
{
e.Cancel = true;
}
break;
}
}
}
фон: Я пишу набор универсальных интерфейсов/классов, которые представляют собой основные компоненты DDD, и я делаю source code available (отсюда необходимость создания дружественных интерфейсов).
Этот вопрос связан с тем, чтобы сделать интерфейс максимально связным, чтобы потребители могли получать и реализовывать свои собственные коллекции, не теряя основную семантику.
PS: Пожалуйста, не предлагайте использовать методы AddXYZ()
и RemoveXYZ()
для каждого списка, потому что я уже отклонил эту идею.
PPS: Я должен включать разработчиков с использованием .NET 2.0 :)
В первом случае вы можете использовать один и тот же обработчик для InsertingItem и SettingItem – RichardOD