BusinessBindingListBase

时间:2016-04-29 06:31:34

标签: c# business-rules csla

我们的应用程序中的业务层使用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)派生的属性实现规则(例如最小/最大计数规则)的正确方法是什么?

2 个答案:

答案 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)

这是为那些目前对此感兴趣的人准备的。我建议在父对象中实现业务规则,传入集合并检查计数。