Aunque BindingList<T>
y ObservableCollection<T>
proporcionar mecanismos para detectar los cambios de la lista, que no son compatibles con los mecanismos para detectar/intercepción cambia antes de que sucedan.Opinión quería: Interceptar cambios en las listas/colecciones
Estoy escribiendo un par de interfaces para apoyar esto, pero quiero expresar su opinión.
Opción 1: Listas provoca eventos para cada tipo de acción
Aquí, los consumidores podrían escribir código como este:
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;
}
}
Opción 2: Listas plantean un solo evento, y la acción se determina desde el evento args
Aquí, los consumidores pueden escribir un código como este:
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;
}
}
}
Antecedentes: Estoy escribiendo un conjunto de interfaces/clases que representan los componentes básicos de DDD de propósito general, y estoy haciendo el source code available (de ahí la necesidad de crear interfaces amigables).
Esta cuestión se trata de hacer la interfaz como cohesiva como sea posible, para que los consumidores puedan obtener y aplicar sus propias colecciones sin perder la semántica del núcleo.
PD: Por favor, no sugieren el uso de AddXYZ()
y RemoveXYZ()
métodos para cada lista, porque ya he descarté esa idea.
PPS: I deben incluir el uso de desarrolladores .NET 2.0 :)
En el primer caso, sin duda puede usar el mismo controlador para InsertingItem y SettingItem – RichardOD