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:リストは単一のイベントを発生させ、アクションはイベント引数から決定されます
ここで、消費者は次のようなコードを書くかもしれません:
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のコアコンポーネントを表す一連の汎用インターフェイス/クラスを作成しており、ソースコードを利用できるようにしています(したがって、使いやすいインターフェイスを作成する必要があります)。
この質問は、消費者がコアセマンティクスを失うことなく独自のコレクションを導出および実装できるように、インターフェイスを可能な限りまとまりのあるものにすることに関するものです。
PS:私はすでにそのアイデアを割り引いているので、各リストの使用AddXYZ()
と方法を提案しないでください。RemoveXYZ()
PPS:.NET2.0を使用する開発者を含める必要があります:)