2016-04-29 21 views
1

Die Business-Schicht in unserer Anwendung verwendet CSLA.NET. Ich habe Business-Klassen namens Invoice und InvoiceItem (abgeleitet von einer Unterklasse von CSLA BusinessBase) und InvoiceItemList (abgeleitet von einer Unterklasse von CSLA BusinessBindingListBase).CSLA.NET Min/Max-Zählregel für BusinessBindingListBase

Rechnungsklasse eine Eigenschaft für Objekte hat, erklärt, wie:

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); 
    } 
} 

ich eine CSLA Business Rule implementieren möchten, die sicherstellt, dass Rechnung nicht ohne mindestens ein Element gespeichert wird. Daher habe ich eine MinCount-Regel erstellt, die von CSLA PropertyRule abgeleitet wurde und sie auf die Items-Eigenschaft angewendet hat.

BusinessRules.AddRule(new MinCount(ItemsProperty, 1)); 

Das Problem ist, diese Regel nur, wenn SetProperty auf ItemsProperty genannt wird abgefeuert wird, die nur einmal (in DataPortal_Create) genannt wird. Zum Zeitpunkt der Erstellung sind keine Elemente vorhanden, daher markiert die Regel das Objekt korrekt als ungültig. Die Regel wird jedoch nicht ausgelöst, wenn InvoiceItem-Objekte zur Items-Eigenschaft hinzugefügt/entfernt werden. Das Invoice-Objekt bleibt daher ungültig und wird nicht gespeichert.

Wie können Regeln (z. B. Min/Max-Zählregel) für Eigenschaften, die von BusinessBindingListBase (oder BusinessListBase) abgeleitet sind, ordnungsgemäß implementiert werden?

Antwort

1

Ich schrieb den folgenden Code, um meine Min/Max-Regel auszulösen.

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); 
} 

Der obige Code behandelt nicht das Szenario, in dem es mehrere List-Eigenschaften desselben Typs gibt. Der Code könnte ein Where (anstelle von FirstOrDefault) verwendet haben, um alle diese Eigenschaften zu durchlaufen. Der Nachteil ist, dass die Änderung dann unnötig für andere Eigenschaften ausgelöst würde.

+0

Sie können filtern, um nur diesen Code auf bestimmten Listen auszuführen, indem Sie 'if (e.ChildObject ist InvoiceItemList) {// tun Zeug}' – Andy