private static void Rule1(This is interesting because an "outargs" object is passed into the method with defaults such as Severity, Description, PropertyName, etc. But it is also passed back into the result delegate and handled by the broken rules collection.
object target,
AsyncRuleArgs inargs,
AsyncRuleResult outargs,
AsyncRuleResultHandler result)
{
BackgroundWorker worker = new BackgroundWorker();
worker.DoWork += (s, e) =>
{
string propertyName = inargs.PropertyName;
object foo = ((Rule1Args)inargs).Foo; // use custom rule args
// some asyncrhonous work will be done...
e.Result = true;
};
worker.RunWorkerCompleted += (s, e) =>
{
outargs.Result = (bool)e.Result;
result(outargs);
};
// simulating an asynchronous process.
worker.RunWorkerAsync();
}
private static void Rule1(So the question really is, what is more intuitive? What would you prefer to see? Is it intuitive enough to have a method on the incoming argument that must be called, or is it more clear to have it as it's own parameter? Should the incoming arguments be associated with the result object, or is it more clear to be a seperate parameter? What is better, simplicity or being explicit?
object target,
AsyncRuleResult r)
{
BackgroundWorker worker = new BackgroundWorker();
worker.DoWork += (s, e) =>
{
string propertyName = r.Args.PropertyName;
object foo = ((Rule1Args)r.Args).Foo; // use custom rule args
// some asyncrhonous work will be done...
e.Result = true;
};
worker.RunWorkerCompleted += (s, e) =>
{
r.Result ( (bool)e.Result ); // the delegate is on args
};
// simulating an asynchronous process.
worker.RunWorkerAsync();
}
Another option might be to have a method on the args to do the callback in an even more abstract manner:
r.Complete(true);
So really there are at least three options:
I kind of lean toward option 3 because it totally hides the delegate and potentially provides the best abstraction.
But we've posted this thread to solicit input from others in the community, so chime in if you have an opinion - otherwise you'll have to live with our choice :)
I guess some more context might be in order - come to think of it.
In Silverlight all server communication is asynchronous. That's just the way it is.
So CSLA Light has an asynchronous data portal. Instead of Fetch(), there's BeginFetch() with an asynchronous callback that occurs when the operation is complete.
To keep parity, CSLA .NET 3.6 also has an asynchronous data portal - as an option. It has the same API as the CSLA Light version. That's pretty cool by itself imo :)
Sometimes you write a validation rule that has to talk to the server. Perhaps an Exists() check that runs a stored procedure via a Command object or something like that. This is not uncommmon.
Since the data portal is async, this means that the validation rule must be async too!!
That's a problem, because the validation rules subsystem is all synchronous now. So Justin has put a lot of work into enabling async rules alongside the sync rules.
The end result is that you can either write a sync rule like today, or an async rule. If you write an async rule, then in the callback you need to tell CSLA Light that the rule is complete - and that's the question here - how do you tell CSLA that the rule is complete (and that it succeeded or failed)?
I lean towards #3 also.
I prefer to hide as much complexity as possible.
Keep things as simple looking as possible on the surface.
Joe
Copyright (c) Marimer LLC