there is a similar use case in ProjectTracker:there are no more 5 resouces in a project.
private static bool No5Resources<T>(
T target, Csla.Validation.RuleArgs e) where T : Project
{
if (target.Resources.Count>5)
{
e.Description = "Already 5 resources in the project!!";
return false;
}
return true;
}
void Resources_ListChanged(object sender, System.ComponentModel.ListChangedEventArgs e)
{
//bind the validation to Name Property
PropertyHasChanged("Name");
}
//if the project object is retrieved from database
protected override void OnDeserialized(System.Runtime.Serialization.StreamingContext context)
{
this.Resources.ListChanged -= new System.ComponentModel.ListChangedEventHandler(Resources_ListChanged);
this.Resources.ListChanged += new System.ComponentModel.ListChangedEventHandler(Resources_ListChanged);
base.OnDeserialized(context);
}
//if the project object is newly created
protected override void DataPortal_Create()
{
_id = Guid.NewGuid();
_started.Date = DateTime.Today;
this.Resources.ListChanged += new System.ComponentModel.ListChangedEventHandler(Resources_ListChanged);
ValidationRules.CheckRules();
}
all these code in project calss.
I often put those kind of rules in the Root BO that contains the collection. Then the root BO can ask the collection questions like "How many resources do you have?" Or "what are your locations and are any of them duplicates". The root BO can keep track of which child object broke the rules and expose a broiken rule accordingly.
I will usually call these extra rules in IsValid just before getting the real value for IsValid - this gives them a chance to become broken or not one last time. I may sometimes write a lengthy procedure to figure this out and pass in stringbuilder and then append each problem to it so the full message is returned to the calling method.
Joe
JoeFallon1:I often put those kind of rules in the Root BO that contains the collection. Then the root BO can ask the collection questions like "How many resources do you have?" Or "what are your locations and are any of them duplicates". The root BO can keep track of which child object broke the rules and expose a broiken rule accordingly.
In my BusinessListBase I have added a AddConstraintCheck virtual method that gets called on any add/set, and a DeleteConstraintCheck that gets called on any delete/remove. This could easily be expanded to use delegates to have multiple reusable checks but in all my cases this simpler aproach works.
Note that I don't throw an exception, I leave that to the AddConstraintCheck method, that way if duplicates are expected and to be ignored the developer can choose to not throw an exception.
public new void Add(C item)Unfortunately that solution isn't safe, because there are several other ways to get items into a collection beyond the Add() method. And in any case, shadowing a method is something that should be avoided if at all possible.
The better solution is to override the InsertItem() and SetItem() methods. These are invoked by the base collection class when an item is inserted (in any way) or replaced within your collection.
These methods are invoked during the add process - before the item has been added. If you do not call base.InsertItem() or base.SetItem() the add won't occur, and if you do cascade the call then the add will complete.
But these methods are the location where you should invoke your validation method, because then you are sure to have your code run in all cases.
Yeah I realized after I posted that what I posted was incomplete, my BusinessListBase has a lot of additional functionality and seperating the other stuff out I overload AddNewCore to provide polymorphic core creation when polulating a list from a database and a whole bunch of other stuff.
In my code I handle InsertItem and SetItem, I've just been knocking my head against the wall trying to figure out what broke with 3.0 in BusinessListBase and the EditLevel, since I have so many updates its difficult to tell if it's me or the beta, my 2.0 based BusinessListBase works perfectly.
I should start a different thread, but when a BusinessListBase class is a child of a BusinessBase, when AcceptChanges is called on the BusinessBase class the AcceptChanges of the child BusinessListBase class always throws an exception that it is not at the same edit level (it always appears to be zero at the acceptchanges call). The other nested BusinessBase objects all are at the right EditLevel, so trying to hunt this down to see if its me or not.
John
What changed in 3.0 is that I added this new exception that you
are seeing. The reason for adding the exception is to help troubleshoot bugs
around edit level handling, because if you don’t find them then they mess
up data binding in very-hard-to-diagnose ways.
If you got the code from svn then it should be working. My tests
(unit and otherwise) include using a BLB as a child of a BB, and my tests all
pass.
Rocky
From: jtgooding
[mailto:cslanet@lhotka.net]
Sent: Thursday, May 31, 2007 7:43 AM
To: rocky@lhotka.net
Subject: Re: [CSLA .NET] BusinessListBase validation - only one child
with property == 'xyz'
Yeah I realized after I posted that what I posted was incomplete, my
BusinessListBase has a lot of additional functionality and seperating the other
stuff out I overload AddNewCore to provide polymorphic core creation when
polulating a list from a database and a whole bunch of other stuff.
In my code I handle InsertItem and SetItem, I've just been knocking my head
against the wall trying to figure out what broke with 3.0 in BusinessListBase
and the EditLevel, since I have so many updates its difficult to tell if it's
me or the beta, my 2.0 based BusinessListBase works perfectly.
I should start a different thread, but when a BusinessListBase class is a
child of a BusinessBase, when AcceptChanges is called on the BusinessBase class
the AcceptChanges of the child BusinessListBase class always throws an
exception that it is not at the same edit level (it always appears to be zero
at the acceptchanges call). The other nested BusinessBase objects all are
at the right EditLevel, so trying to hunt this down to see if its me or not.
John
Copyright (c) Marimer LLC