我们的应用程序中的业务层使用CSLA.NET。我有名为Invoice和InvoiceItem的业务类(派生自CSLA BusinessBase的子类)和InvoiceItemList(源自CSLA BusinessBindingListBase的子类)。
Invoice类具有Items的属性,声明为:
private static readonly PropertyInfo<InvoiceItemList> ItemsProperty =
RegisterProperty<InvoiceItemList>(o => o.Items, RelationshipTypes.Child);
public InvoiceItemList Items
{
get
{
return GetProperty(ItemsProperty);
}
private set
{
SetProperty(ItemsProperty, value);
}
}
我想实施一个CSLA业务规则,确保在没有至少一个项目的情况下不保存Invoice。因此,我创建了一个MinCount规则,该规则源自CSLA PropertyRule并将其应用于Items属性。
BusinessRules.AddRule(new MinCount(ItemsProperty, 1));
问题是,只有在ItemsProperty上调用SetProperty时才会触发此规则,而ItemProperty只调用一次(在DataPortal_Create中)。创建时没有项目,因此规则正确地将对象标记为无效。但是,当InvoiceItem对象添加到Items属性/从Items属性中删除时,不会触发规则。因此,Invoice对象仍然无效,并且未保存。
为从BusinessBindingListBase(或BusinessListBase)派生的属性实现规则(例如最小/最大计数规则)的正确方法是什么?
答案 0 :(得分:1)
我最终编写了以下代码来触发我的最小/最大规则。
protected override void OnChildChanged(ChildChangedEventArgs e)
{
base.OnChildChanged(e);
// We are only interested in some change in a List property
if (e.ListChangedArgs == null || e.ChildObject == null) return;
// We are only interested in addition or removal from list
if (e.ListChangedArgs.ListChangedType != ListChangedType.ItemAdded
&& e.ListChangedArgs.ListChangedType != ListChangedType.ItemDeleted)
return;
// Find property by type
var t = e.ChildObject.GetType();
var prop = FieldManager.GetRegisteredProperties().FirstOrDefault(p => p.Type == t);
// Raise property change, which in turn calls BusinessRules.CheckRules on specified property
foreach (prop != null)
PropertyHasChanged(prop);
}
以上代码不处理存在多个相同类型的List属性的场景。代码可以使用Where(代替FirstOrDefault)来遍历所有这些属性。缺点是对其他属性不必要地进行更改。
答案 1 :(得分:0)
这是为那些目前对此感兴趣的人准备的。我建议在父对象中实现业务规则,传入集合并检查计数。