Ok, I just found the best site I’ve stumbled across in a long time.

http://www.antiifcampaign.com/

Excellent job guys and mad respect for giving this issue it’s very own online site/campaign. Join me and the many others to move the community in a positive direction. BTW, I found this indirectly on a great post about the subject by elegantcode.com.

If you don’t remember, I disscussed this a while ago with What-if if is evil? But I would be remiss to avoid mentioning that the if keyword is not the only way to write branches in your code. There are plenty of other keywords (switch, while, try/catch) that can produce the same issues. The idea should be to create functions/methods with the fewest code-paths as possible. This creates code that behaves more consistently, predictably, and is easier to read and test. This is especially important when writing code in a Form or ASP code-behind.

 

I hate to say this since I’m sure many people put a lot of time and energy into this … but I truly HATE CSLA for .Net. Why? Several reasons, however, as a fore-note about my point of view you should take this into consideration. My experience with CSLA used about 10% of the features, the added complexity of the other 90% caused many of the issues below.

Debugging
CSLA biggest problem (IMO) is that much of the code utilizes reflection. This results in several problems, however, one big one is the age-old issue with generating TargetInvocationException. The issue here, if you’ve never experienced it, is that this generic ‘wrapper’ exception causes a loss of the original exception type. If, for example, you are handling an access denied exception (UnauthorizedAccessException) then this wrapper exception can hide it from you causing unexpected/undesired behavior. The common answer for this is to wrap the reflection with a catch(TargetInvocationException) and rethrow the inner exception. This too causes problems as your stack is now reset on the exception and you have no idea where inside the reflected code it failed. This has caused me untold problems while debugging/diagnosing CSLA implementations.

Implementation
I don’t even know where to begin with this one. I fundamentally disagree with the entire model promoted by CSLA. Make an object, call a bunch of setters, pray it’s valid, call save. This approach kills me… setters kill me (at least outside a data layer)… Objects should be valid at construction, not made valid thereafter. For instance, if your “user” object requires a user name and password to be valid it should be required before the object is constructed. After construction, if you decide to fill in the first/last name ect then great, but their defaults are valid. If you now need to refactor this ‘user’ object to also require an email address, you simply need the newly required param to the construction of the object and your compiler will tell you where to update dependent code. You can also choose to obsolete the original method and introduce a new one that requires the email to preserve compatibility. The CSLA model does not allow you to identify at compilation what objects are being correctly populated with all required properties. This is the fundamental problem with the setter/save object construction pattern. Objects should always be valid. period.

This doesn’t touch the surface of the problems. Another big issue I have is the reliance on base-classes. Implementing a CSLA object requires deriving from common base classes that are not in your control. Issue you say? Yes it is, every project that uses your business layer must now additionally reference the CSLA library as required by the compiler. Moreover you tend to rely on these base classes in your code further binding you to CSLA. Essentially the decision to use CSLA on a project is an irrevocable one. Instead, this entire library *should* have been implemented using a services model and provided an interface abstraction to ensure that you are not utterly dependent on the continued use of CSLA. This abstraction would also greatly aid in the testability of the code as you can now stub these interface implementations for isolation of business logic while testing.

Thread Safty
Most of you are going huh at this one… believe it or not there are several aspects of CSLA that are not thread safe while accessing global data. This can cause exceptions and unexpected behavior without you doing anything wrong. You don’t need to share an object between threads, just have several threads accessing CSLA and sooner or later — boom. This is common enough if you consider the average website provides a multi-threaded environment that can easily encounter these issues. WTF, global data is bad, bad in C++, bad in ANSI C, and still bad today. We have been forced to crack the code to fix several of these issues.

</rant>