Hi all,
Evaluating CSLA for a new project and running into questions regarding running a business rule in the context of the operation being performed. It appears that in CSLA, the objects have a sense of their own business rules, but not necessarily of rules that should be applied in relation to other objects in the operation.
Making up a example on the fly here...
Let's say I have a form on which I'm entering data for a new Factory, as well as a new Customer. Each of these objects has a country associated with it. For whatever reason, we don't want these country values to be the same (probably not a great example, but bear with me). So if one enters France for the country values of both of these objects, the business rules pass for the objects individually but there's no check done of the other object to see if these country values are equal.
In the past, I might have hooked up the submit to a static class on the server checking this like:
public static SubmitCustomerAndFactory(Customer customer, Factory factory, ...)
{
if (customer.Country == Factory.Country)
throw...
}
It's probably not too hard to pick apart this example, but hopefully the point was expressed. How might one use the business rules framework to apply rules not only to individual objects, but *across* objects depending on the operation? The mobile business objects are intelligent, but aren't necessarily aware of the overall context they're contained in. How might this be worked around without coding this logic invidually into client and server?
Thx,
Glenn
That helps to some extent.
What I'm really driving at though is that having business rules only within the individual objects isn't always realistic. There are often rules that depend on the context of the overall operation in which the object is contained, whether they're rules within the objects in question that might or might not be applicable, or rules relating to different objects in the operation. In a perfect rule, the classes and their relationships can be configured so that there are parent-child relationships like this, but this doesn't always happen in practice as the use cases get larger.
Maybe I can come up with a better example...
Glenn,
My BOs are a bit on the data centric side but I think that is OK because I usually wrap them in a Root level BO which is a Use Case Controller object. I originally called it a Unit of Work but later learned that means something different than what I am using it for - so all my controler objects end with a 'UOW' suffix.
Anyway, the point is that for a given use case, the UOW object is loaded and then fetches the other BOs required to satisfy the use case. They can be root BOs with child collections, or a bunch of NVLs or, whatever you need to fetch.
The UOW object thus knows which other BOs are contained in it and you can write a set of high level rules which cross each of the lower level contained BOs. You also override IsValid and IsDirty so that you know if the UOW is valid or dirty by looking at its contained objects as well as any properties it may have on its own.
This pattern has worked very well for me (for over 4 years) and the Codesmith templates that I use to generate BOs.
Joe
That sounds like one of the approaches I was considering. The back-end may have to support several versions of the front-end, so I'm intentionally keeping the BOs more granular than if I knew all of the specifics of the front end. The business cases will change to some extent as well, so granularity might better support this. The 'wrapper' class you say you're using sounds like it might fit the bill.
Mind sharing more of the specifics of an implementation of this wrapper (maybe just pseudocode if it's lengthy)? Anything out there you're recommend for starting code generation for my table-centric cases? Or did you roll your own from scratch?
Thanks again to all repliers,
Glenn
Copyright (c) Marimer LLC