Reasons to Stay Away from CSLA

We've been using CSLA - Component-based Scalable Logical Architecture in a product for approximately one year and while it solves quite a few problems it violates some major good practices.

No Clear Separation of Layers

While at the time that we chose CSLA we knew very little about domain driven design, it is no excuse for the framework to possess the data access layer within the business object. This makes it extremely difficult to separate the concerns. As a result, it is difficult to mock the data-access layer creating many problems when attempting to perform unit tests. This also puts the additional responsibility of data access on the business object class, violating the Single Responsibility Principle(SRP). Data access layer should be totally separated from the business object period. Having the data access within the within the BO class is not the only additional responsibility placed on the class but is the most significant one I can think of.

No Context Validation

In the CSLA a business object is either valid or not. That, we found out after some hard knocks, is the wrong way to approach validation. Validation should be based on context. A business objects rules for validity depend on the context in which it is being used. Martin Fowler makes this a clear point In certain situations we found that we could not properly save an object because it was in an invalid state from a given view because it had certain required fields even though the fields were not visible in the form. The rule was valid from a different view but not from the one were it got stuck. This lead us modify CSLA base classes so that we had to turn rules off and on on-demand. In the end this created some really nice spaghetti code - Ragu anyone?

Having only the IsValid property as way to determine the validity of an object made for some ugly unit tests. As an example you would have to test the IsValid property for true, set a property to an invalid value, and test the IsValid property for false. You could never simply test the CheckRule method directly since it was part of the delegate fired deep within the base class.

No use of abstractions

In many cases many of the methods used by classes of the framework rely on parameters of the object type. Then the object is either cast to the appropriate object or reflection is used to called a magic method (i.e. DataPortal_Update(), DataPortal_Fetch(), etc). A better solution would have been to rely on interface definitions so that the methods could be called directly instead of calling them through reflection. Following the methods in debug mode is extremely tedious due to all the reflection going on.


Please keep in mind that the version of CSLA that this information is related to is 1.x. I realize and have heard that later versions are much better but I seriously doubt they tackle the problems mentioned above. In my next project I will use POCOs (Plain Old C-Sharp Objects) that know nothing about persistence and are not so feature rich. I didn't elaborate on all the nit picky stuff I could get into about what's wrong with the CSLA but if this isn't enough to keep you away from it be my guest - I will be the one saying "I told you so!".


Anonymous said…
What's funny is that I've been preaching POCOs for all the time I've been at my present job. I liken programming to professional basketball. The basics and fundamentals of basketball are taught at an early age. When players get to the pro's, for the most part, they stop using the basic fundamentals; like boxing out to grab a rebound, cutting off the baseline and forcing their opponent back to the middle of the floor, etc...

The point is, you have very talented developers that would like to use the latest development tools and methods, but the basics will always pull you through. You can get yourself into uncharted territory when you attempt new thing. Just ask Shaq when he tries to shoot a three-pointer when his skill level is really inside of the key.

Michael Adkins
Nolan Egly said…
Context is HUGE with entities, so much to the point that sometimes I'll model the same data in the database with multiple entities to cleanly deal with differing contexts.

Welcome to blogging, BTW. Looking forward to more!
Brendon Webber said…
I've been using CSLA for 12 years now and do not really agree with your comments.

For the most part the DAL is within the class, but ALWAYS gets executed through the DataPortal and can even be run remotely. Yes, an instance of the object is still performing the CRUD operations. If this is not enough separation for you, you can quite easily create a separate class for the DAL and use an Object Factory design pattern to do the Data Access for you outside of the business objects.

Personally, I like having the data access code within by business object. If a new field is required I make all the changes to a single class (property, fetch/insert/update, rules etc.). If the UI layer is clever enough, it often automatically picks up these changes automatically.

On the rules side I do see your point. I get around this by adding some sort of context based property to my business object that gets included in my rule code. I.e. if I have a single object that flows through some sort of workflow, by changing the status from step to step I can ensure that the right rules are enforced when necessary.
Fernando Zamora said…
I haven't followed CSLA much since I wrote this article. Perhaps it's gotten better. The pain points that I pointed out were from what we were experiencing during that time. At the time the big benefits of the CSLA were the N-Level undo and Remoting which in the end were not necessary. However CSLA led us down the path of having bloated business objects. Perhaps we didn't use it properly but we used it according the manual C# Business Objects. I've heard other people have used it with great success. I just think that it over complicates things in many areas. At least it seemed that way six years ago.
Anonymous said…
As someone that still has to use CSLA ... No it hasn't gotten any better.

The idea of contextual validation is a huge, huge gaping whole that CSLA chooses to ignore. The way the rules are run and created is exceptionally hokey (yes the rules are classes but there is really only one instance so make sure your rules are thread safe).

The fact that everything is a static makes it exceptionally hard to replace at unit test time. It also make dependency injection a real nightmare.

Let's not forget so flippin' slow it is with all the reflection.

At all costs steer clear.

Popular posts from this blog

Simple Example of Using Pipes with C#