Re: Weak points in the framework. Do they exist?

Re: Weak points in the framework. Do they exist?

Old forum URL: forums.lhotka.net/forums/t/4128.aspx


RockfordLhotka posted on Sunday, January 06, 2008

With any framework it is important to understand, and accept, the philosophy and goals on which the framework is founded. This is the purpose behind Chapters 1 and 2 in the book, to explain the philosophy, goals and resulting design choices I have made.

I’ve blogged about a lot of this numerous times, but here’s a short and sweet summary of my (and thus CSLA’s) philosophy.

CSLA .NET is a client/server, n-tier development tool. Its primary purpose is to make it easier to build a powerful, feature-rich and .NET-integrated business layer composed of business objects. Those objects are ideally designed using single-responsibility design.

The other primary purpose of CSLA .NET is to enable flexible deployment of the business layer on a single machine, or on both a client and server. This uses the concept called mobile objects, which is strictly an n-tier concept.

N-tier directly implies that you are building an application with multiple layers, where those layers are deployed on 2 or more physical tiers (some inter-layer communication at least crosses process boundaries, if not network boundaries). However, it is an architecture for building an application. Singular.

An application describes a “trust boundary”. By which I don’t just mean security, but also semantic trust. N-tier applications rarely re-apply all business logic on every tier. That is incredibly expensive and inefficient in many ways. And it is pointless, because all the tiers live within this trust boundary.

If you have code that will run outside the trust boundary of your application then you have, by definition, two applications. It is not possible for an application to span a trust boundary.

When you have two applications, they should communicate with each other using message-based techniques. These days this is often called “SOA”, and so the techniques are now “service-oriented”. Regardless of the terminology, the point is that you have two applications, one on either side of the trust boundary. The only thing flowing across the trust boundary is raw data in the form of messages (XML or otherwise).

Neither application trusts the other. In many cases this means both applications will implement the same logic. At least the same validation, but often the same calculations and data manipulation. The client application does this to provide the user with a decent user experience. The server application does this because it doesn’t trust the client application. So they both do it.

If you really want to be service-oriented, you won’t try to share code between these two applications. If you do that, you lose the primary benefit of SOA, which is decoupling and version independence. But that is really expensive, because you must then implement and maintain two applications that have much of the same logical code.

But if all you want is to safely traverse the trust boundary, and you don’t care about being “SOA” or loosely coupled or version independent, then you can share code between the two applications. You can build them both against the same business DLL. This business DLL can be created using CSLA .NET if you like.

Which ultimately brings us to the issue of data access code in the DataPortal_XZY methods. This too is a topic I’ve discussed many times, but here’s a quick summary.

The DataPortal_XZY methods really only have one purpose: to trigger interaction with the data persistence mechanism. They don’t have to include or even implement the data persistence, they just need to trigger it.

However, the data access mechanism does need to get and set the object’s field data. Fields are private. So you are left with two real options: get/set the fields in the DP_XYZ methods, or externalize the get/set operation.

If you externalize the get/set operation you have two basic options: somehow make the fields non-private (make them protected, expose them via an interface, etc) or you use reflection. Making the fields non-private is an unsound idea for very obvious reasons. Using reflection is slow.

So personally I recommend leaving the field get/set behavior in the DP_XYZ methods. That is meaningless code anyway – there’s no security benefit to be gained by protecting code like

X = Y;

A = B;

C = D;

 

Really, who cares?

What you do want to externalize is the code to open the database and execute the SQL. Well, really what you want to externalize is the SQL.

And you can do that very effectively. See the DeepData example on my web site, or attend Dunn Training’s CSLA .NET training class to see this idea in action.

But even externalizing the SQL isn’t enough if you want to re-use the business layer in two different applications. The reason is that the client application will almost certainly consume and produce DTOs to send as messages across the boundary. The server application will almost certainly use ADO.NET to talk to the database.

So what you really need is a more complex architecture where the DP_XYZ methods always consume and produce DTOs. Your client application’s “DAL” then ships those DTOs to/from the server application, while the server application’s DAL puts the DTO data into/out of the database using ADO.NET. Or LINQ.

So the application stack (with both applications) looks like this:

Client Presentation

Client UI

Business Objects (CSLA)

DTOs

Client “DAL” (service calls)

<------- trust boundary ----->

Service Presentation (XML)

Service UI (actual service code)

Business Objects (CLSA)

DTOs

Service DAL (ADO.NET, LINQ, etc.)

 

Both applications follow the same basic architecture – the one from Chapter 1 in my book. Both business object layers can be the same (again, assuming you don’t care about being “SOA”). The DTO layers need to be the same as well, because they are the official contract followed by the DP_XYZ methods. But the DAL implementations are obviously radically different from each other.

And really, if you are willing to use dynamic language features like those in VB, Ruby or Python, then the DTOs don’t need to be the same type, they just need to have the same shape. But if you want to stick with strong typing (like C# or VB without the dynamic options turned on) then they need to be the same type.

Copyright (c) Marimer LLC