Vij*_*tel 5 c# domain-driven-design bindinglist observablecollection
虽然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;
}
}
Run Code Online (Sandbox Code Playgroud)
选项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;
}
}
}
Run Code Online (Sandbox Code Playgroud)
背景:我正在编写一组代表DDD核心组件的通用接口/类,我正在使用源代码(因此需要创建友好的接口).
这个问题是关于使界面尽可能具有内聚性,以便消费者可以在不丢失核心语义的情况下派生和实现自己的集合.
PS:请不要为每个列表建议使用AddXYZ()和RemoveXYZ()方法,因为我已经打了折扣.
PPS:我必须包括使用.NET 2.0的开发人员:)
相关问题.
我建议创建与ObservableCollection<T>适当的地方相似的东西.具体来说,我建议遵循现有的收集变更通知技术.就像是:
class MyObservableCollection<T>
: INotifyPropertyChanging, // Already exists
INotifyPropertyChanged, // Already exists
INotifyCollectionChanging, // You'll have to create this (based on INotifyCollectionChanged)
INotifyCollectionChanged // Already exists
{ }
Run Code Online (Sandbox Code Playgroud)
这将遵循既定模式,以便客户端已经熟悉暴露的接口 - 已经存在三个接口.使用现有接口还可以与其他现有的.NET技术进行更好的交互,例如WPF(INotifyPropertyChanged与INotifyCollectionChanged接口绑定).
我希望INotifyCollectionChanged界面看起来像:
public interface INotifyCollectionChanged
{
event CollectionChangingEventHandler CollectionChanging;
}
public delegate void CollectionChangingEventHandler(
object source,
CollectionChangingEventArgs e
);
/// <remarks> This should parallel CollectionChangedEventArgs. the same
/// information should be passed to that event. </remarks>
public class CollectionChangingEventArgs : EventArgs
{
// appropriate .ctors here
public NotifyCollectionChangedAction Action { get; private set; }
public IList NewItems { get; private set; }
public int NewStartingIndex { get; private set; }
public IList OldItems { get; private set; }
public int OldStartingIndex { get; private set; }
}
Run Code Online (Sandbox Code Playgroud)
如果您希望添加取消支持,只需添加一个可写bool Cancel属性CollectionChangingEventArgs,该集合将读取该属性以确定是否执行即将发生的更改.
我认为这属于你的选项2.这是要走的路,因为要与监控不断变化的集合的其他.net技术进行适当的互操作,你无论如何都必须实现它INotifyCollectionChanged.这绝对会遵循您界面中"最少惊喜"的政策.
| 归档时间: |
|
| 查看次数: |
888 次 |
| 最近记录: |