I'd like to ask a question based on Rocky's suggestion here (to a different problem) about re-using and extending objects. His quote:
"I've said this so many times I can't count - it is always a good practice to create a set of custom base classes that sit between the CSLA base classes and your business classes. This is the primary extensibility model for several aspects of CSLA, including things like business rules, validation rules, authorization and the data portal."
With this in mind, if you create a base readonly object, is it recommended to leave the DataPortal_Fetch method empty in your base class and instead code it in your extended objects? Or do you code it in the base class and just override it in the inherited class? Consider the following:
What about the DAL (we're using encapsulated invocation)? Do you have one DAL that is used across the objects and pull all possible fields in there? Or separate DALs, one for each object? It would seem like you wouldn't want to always pull 20 fields from the database if the object is only going to use two of them.
Your custom base classes provides extensibility for behavior.
Think, f.ex logging, timing data, exception logging.
You should NOT implement DataPortal_Fetch/Delete/Update in these classes. .
These methods should be implemented in the actual business objects.
DAL's can be coded in so many different ways.
I like Linq2Sql and EF - where it's up tp the developer to either get anononymus types or defines types. When using anonymous types (result not defined in your enitity model) you cannot send it as a "well defined" parameter to other objects so I prefer so have each object implement their own mapping logic between the Data objects and the business object.
On a personal not - I prefer ObjectFactory but that is just my personal preference as it keeps my BO's totally clean from any type of Data Access types, whether is be a SQL Database, REST service, WebService or proprietary data access technology.
Thanks. So by "behavior" do you mean only those examples such as logging, or are additional properties included in that reasoning?
Is my outline of the BaseCustomerInfo and subclasses not a correct usage of it? In other words, is it not meant to create my own base CSLA class and provide the standard properties / rules / auth that every app would need and just allow subclasses to extend those properties/rules/auth, as needed?
You can create base objects with properties and authz/business rules.
The problem is that you get a very strong coupling and especially rules can be cumbersome.
So, I have created some objects with common properties but always try to avoid adding authz/business to base classes.
Rules, in my experience, is not easily extendable and will often vary between subclasses (think f.ex corporate/private customer) .
So as a general recommendation - try to avoid adding business/authz rules to base classes.
The philosphy of the CSLA rules engine is that rules are first-class citizens. They are objects (and therefore can be tested, reused, etc).
Rules are then attached to properties of editable objects. Unless your class defines a property, the class can't do anything with rules, because it won't have anything to which the rule should be attached.
Typically you should avoid defining properties in base classes, primarily because it complicates the data access process substantially and really breaks down any sense of organization or abstraction in your code. So if you don't have properties in the base class, then you wouldn't attach rules in the base class either, so that limits the sorts of things you might do in a base class.
So what I hear you both saying is that unless I want to do behavioral things like logging (as Jonny stated) I shouldn't create a bass class just to add common properties.
This takes me back to what really prompted me to ask about this: what is the general practice when creating or extending objects for use in two or more apps that each have slightly different needs? If the use case between the two is only slightly different, do you just make one object flexible enough to serve both needs? Or do you adhere to a hard rule of saying that any difference in use case leads to a totally new object? Again, the current scenario in my mind is a CustomerInfo object. One app might need 3 properties displayed, while another might require 8 properties. Do you just add the 5 extra to one object and re-use between the two apps even though the one app will be pulling over 5 extra properties that it really doesn't need? Thanks, again.
The pitfall that many developer experience with CSLA BusinessObjects is thinking of entities (as you would in a database/DAL).
Your BO should be shaped as per the use case and if there is a 1:1 relationship you will be better off by having all these properties in the same BO.
IE: The BO's should be shaped as per the UseCase - do not think entities. If they have different fields and rules then I'd rather have them as separate objects as it makes my code more maintainable.
This will also simplify your business rules.
The following is coming from a n00b over here ... I also strongly feel that your business object should be based on how you are going to use it (E.G., use case) and all of your entities shouldn't be modeled like entities in an ORM.... But, I don't completely agree with the statement above saying that all of your properties should be in the same BO.
I think that TSF's point is perfectly valid for wanting to have a base class implementation, it makes sense (sometimes like when it is in the same project, against the same DataSource...). I agree with both you and Rocky on the fact that one should understand the complexities involved in this task as well as some of the implications that are involved. But I think its crazy to throw code reuse out the window . From the sounds of it, he could get around the Rule issues with a virtual method that is overridden when adding or *changing* BO rules. Please correct me if I'm wrong.
I did this with a prior version of CSLA, and I now have another case where I'd like to be able to do something like this. I understand that inheritance of base business objects adds some complexity, and I know it's a tricky case to model into the framework, but I think it's important to acknowledge that there are cases where there's a real need for something like this.
The business scenario I'm looking at is one where there are several dozen forms that users can fill out. Although each of these forms is unique somehow, there's a set of rules that *all* of them are supposed to enforce. In the current (non-CSLA) system, since the forms are all different in some way, each of these forms is represented by its own chunk of code, so the common business rules are enforced differently from form instance to instance.
I'm trying to drill into business people the need to have business rules managed in a way that ensures that they're coded and executed consistently (thus, the appeal of a framework like CSLA), and to have to turn right around and code a couple dozen business objects that repeat the same rules in "n" places is pretty hypocritical of me, IMO.
I haven't yet started prototyping a solution with a current version of CSLA yet, so I'm not sure if the new approach for rules will work better than in previous versions, but I wholeheartedly support the idea that "don't do that" isn't really an answer to this type of inheritance.
I would not advocate implementing a rule more than once. In fact, the whole point of the system is so you can implement a rule, along with tests, one time, and then just associate that rule with as many properties of as many classes as necessary.
That's certainly true for rules bound to properties, like the CommonRules.
What about a rule, which needs a part of the object graph, i.e. checks that the sum of some property of every children is 100%, or calculation of an amount base on regulations. This is logic, I want to reuse and ensure consistency!
I can see one technique for reusing such a business rule in multiple use cases: the use of interfaces and to code the rule againts the interfaces. As a benefit you get a clear contract between the rule and BOs.
Copyright (c) Marimer LLC