I've been working with Csla for a few months now and am loving it. Though I had a quick question about criteria objects. I need to provide validation logic on the criteria properties to prevent unnecessary calls tp the database. If I understand correctly: since the criteria objects aren't actually part of the objects business validation, I don't get the rich features of Csla validation for these criteria objects...
I assume this is pretty common, and I was hoping to hear what other people have done for this sort of task...
One thing that comes to mind is to use business base for criteria
object. Not that I have ever done that, but I think it should work.
And this will allow you to bind it to UI and user error provider (if you are
using win forms).
Sergey Barskiy
Principal Consultant
office: 678.405.0687 |
mobile: 404.388.1899
Magenic ®
Microsoft Worldwide Partner of the Year | Custom
Development Solutions, Technical Innovation
From: decius
[mailto:cslanet@lhotka.net]
Sent: Thursday, September 25, 2008 9:30 AM
To: Sergey Barskiy
Subject: Re: [CSLA .NET] Validating Criteria Objects
righton, I think it might be handy to write my own
CriteriaBase class for this, any tips and suggestions for that would be great.
There is some overhead to BB for sure in comparison to criteria object.
It will serialize state variables (dirty, etc..). I never actually
compared the size of BB vs. size of Criteria class with the same properties.
I suspect though that the difference is negligible. I guess, it is a
matter of what is more important to you – ease of coding vs. slight performance
hit. Then again, you can have two objects – BB to collect criteria
data in UI, then convert BB to a custom criteria class with the same
properties.
Sergey Barskiy
Principal Consultant
office: 678.405.0687 |
mobile: 404.388.1899
Magenic ®
Microsoft Worldwide Partner of the Year | Custom
Development Solutions, Technical Innovation
From: decius
[mailto:cslanet@lhotka.net]
Sent: Thursday, September 25, 2008 9:42 AM
To: Sergey Barskiy
Subject: Re: [CSLA .NET] RE: Validating Criteria Objects
Yes, I've considered this, but I came to the consideration
that this might be too bulky for a criteria object since this object will need
to be serialized and passed along through the wires.... Perhaps a more
stripped down base class would be more ideal? Or do you think that
BusinessBase wouldn't be overkill after all?
I had to do this once and the path I decided to follow was:
1. Have a BO (deriving from BusinessBase) which defined the criteria (bound to my winform fields) and performed the validation.
2. On my list I had a factory method GetList() which accepted the above BO as an argument.
3. In the factory method I was mapping the values of my BO to the private criteria class which had the same fields defined.
The issue here is that you need to maintain the fields in the BO and the private criteria class in sync. Just my thoughts...
I do steps 1 and 2 all the time. I omit 3 and just use the BO as the criteria itself.
I usually do this for Search forms in my UI. They may have 5 different search terms (First Name, Last Name, Birthdate, State, etc.) Plus they have operators like "Starts With, Contains, etc."
So the BO has a GetFilter property which produces a valid WHERE clause that I can then use in a SQL statement. It omits items that the user did not enter into the Search screen and checks itslef for IsValid before being used for searching the DB.
In fact, Rocky recommends this technique explicitly.
Joe
Joe is right. In fact this is one reason for adding the ICriteria interface - to make it easy for you to use a BusinessBase<T> business object as a criteria, by simply implementing ICriteria (which is easy) as well.
Then you get all the validation/authorization goodness to create your criteria input form, and can directly pass that object through as your criteria.
It is true that there's some extra overhead, but I suggest you try this technique, because the overhead is probably a non-issue 99.9% of the time.
It takes a little creativity, but here’s how I’ve
done it:
1.
Define a property such as OneRequired (of any type, such as
string)
2.
Define a custom rule such as OnePropertyRequired()
3.
Attach OnePropertyRequired() to the OneRequired property
4.
Set OneRequired as a dependent property of all other properties
5.
Bind your UI to OneRequired so the error shows on the UI
I have only done this with WPF in CSLA 3.6, and so used the
csla:PropertyStatus control to display an Information severity icon if there’s
a problem. But you could get similar results in Windows Forms with an
ErrorProvider and Error severity rule.
private
static bool
OneFieldRequired<T>(
T target,
Csla.Validation.RuleArgs e) where T : Project
{
if (target.AllFieldsNull())
{
e.Description = "At least one field must be
filled in";
e.Severity = Csla.Validation.RuleSeverity.Information;
return false;
}
else
return true;
}
private
bool AllFieldsNull()
{
if (!string.IsNullOrEmpty(Name))
return false;
if (!string.IsNullOrEmpty(Started))
return false;
if (!string.IsNullOrEmpty(Ended))
return false;
if (!string.IsNullOrEmpty(Description))
return false;
return true;
}
And in my AddBusinessRules() method:
ValidationRules.AddRule<Project>(OneFieldRequired,
OneRequiredProperty);
ValidationRules.AddDependentProperty(NameProperty, OneRequiredProperty);
ValidationRules.AddDependentProperty(StartedProperty, OneRequiredProperty);
ValidationRules.AddDependentProperty(EndedProperty, OneRequiredProperty);
ValidationRules.AddDependentProperty(DescriptionProperty,
OneRequiredProperty);
I don’t actually even bind the OneRequired property to the
UI directly – I just use it as a target for a PropertyStatus control:
<csla:PropertyStatus Source="{Binding}" Property="OneRequired"
/>
I don’t think that’d work well in WPF though,
because of the way WPF handles PropertyChanged. You’d have to make all
properties inter-dependent on each other to get the warning to disappear
properly wouldn’t you?
Rocky
Copyright (c) Marimer LLC