I've written quite a few custom validation rule handlers in Csla.NET. Some of them hit the server/database to validate properties. Csla 3.6 introduced classes like AsyncRuleHandler, AsyncRuleArgs, AsyncValidationRuleContext etc. Because I don't want to rewrite them all for Silverlight I still use Csla.Validation.RuleHandler under Silverlight as well. So I put a conditional #if SILVERLIGHT/#else/#endif directive in to my handler, like this:
#if SILVERLIGHT
...
DataPortal.BeginExecute<CMDType>(....);
...
#else
...
DataPortal.Execute< CMDType > (....);
...
#endif
Although it works for me just fine, I am not sure if there is any problem by bypassing the new AsyncRule concept? What do I get more when using AsyncRuleHandler?
In SL, all server-side communication is async. So if you have a validation rule that hits the server, it must be async too, by definition.
Any validation rules that don't talk to the server can be synchronous, and probably should be. But any rules that talk to a server must be async, because the result of the rule isn't immediately known - it can't be known until the server-side callback occurs actually.
So while your code may work "fine", you'll find that your rules aren't actually being processed properly, because the command object comes back after your rule is already completed on the SL side...
What we did do to provide parity, is add async rules on the .NET side too. So while you will need to rewrite your rules, at least you can (possibly) make them the same on both SL and .NET.
Ok, but I trapped in the problem that AsyncRuleHandler is missing the "object target" parameter (like RuleHandler). Unfortunately this breaks my current validation code because most of my custom validation rules need to call member functions on the current business object instance before I am calling the server side. Why this restriction? Any suggestion how to get access to the business object instance inside the async rule handler?
Btw: I couldn't find an AddInstanceRule-Method that takes an AsyncRuleHandler and AsyncRuleArgs
We made a conscious choice to disallow using the object instance
from an async rule method. The odds of someone interacting with the object
instance from a background thread would be VERY high – and that’s
totally illegal to do.
So rather than enabling (encouraging?) 99% of people probably do
something wrong, we opted to disallow the more rare case where someone would
interact safely with the object.
Sorry about that, but the alternative (as I see it) would be
utter chaos as most people innocently did the wrong thing.
What we DID do, is allow you to specify all the properties
required by your rule, and those property values are copied and provided to the
rule method. in other words, CSLA takes a copy of all the property values, puts
them into a list, and provides that list to the rule method. This is safe,
because your rule method is now interacting with a snapshot of the values as
they were when the rule was started, and your code can’t accidentally
break any threading rules.
This also avoids nasty race conditions, where property values
change over time WHILE THE RULE IS RUNNING, which could and would happen if you
directly interacted with the object.
It is also true that we didn’t add async rule support for
per-instance rules. if you really look at it, per-instance rules are pretty
broken, because there’s not a great way to add instance rules after the
object has been loaded with data. So you need to load the rules for an instance
before you even know the state of the object – so you can’t really
load conditional rules.
In my view there are much better solutions to any per-instance
requirement by using per-type rules, and I have no qualms about encouraging
people to abandon the use of per-instance rules as being just a bad idea. I
suspect Andres was right – I should have just dropped them entirely in the
2.0->2.1 shift…
Rocky
From: Andreas
[mailto:cslanet@lhotka.net]
Sent: Friday, December 19, 2008 11:39 PM
To: rocky@lhotka.net
Subject: Re: [CSLA .NET] AsyncRuleHandler vs. RuleHandler
Ok, but I trapped in the problem that AsyncRuleHandler is missing the
"object target" parameter (like RuleHandler). Unfortunately this
breaks my current validation code because most of my custom validation
rules need to call member functions on the current business
object instance before I am calling the server side. Why
this restriction? Any suggestion how to get access to the business object
instance inside the async rule handler?
Btw: I couldn't find an AddInstanceRule-Method that takes an AsyncRuleHandler
and AsyncRuleArgs
Copyright (c) Marimer LLC