Chapter 5: Data Access and Security
In Chapter 4, we combined the concepts from Chapter 1, the framework design from Chapter 2, and the technologies from Chapter 3 to create about half of the CSLA .NET framework. In this chapter, we'll continue the process, completing implementation of the remaining classes. This will entail making some minor changes to some of the classes we created in Chapter 4 as well.
Specifically, we'll create the following
And we'll need to add some
Also, we'll create a host application that will run on an application server to host the server-side DataPortal components. This will be a simple ASP.NET application that's configured to act as a .NET remoting host. We'll follow the same process here that we walked through in Chapter 3 when we introduced the concept of using IIS as a remoting host.
Once we've enabled data access within the business framework, we'll
Finally, we'll close the chapter by creating a generic list class to support almost
The classes we'll create in this chapter are as
The reasoning behind each of these classes, and how they are organized into namespaces and assemblies, was covered in Chapter 2. We'll be reprising those discussions as we work our way through this chapter.
A Note About Object-Oriented Programming
One of the primary goals of object-oriented programming is to encapsulate all the functionality (data and implementation) for a domain entity into a single class. This means, for instance, that all the data and implementation logic for the concept of a customer should be in a Customer class.
A corollary to this is that an object should avoid externalizing its data, so that other code can interact with that data. Anytime an object makes its internal data available to other code, the object loses control over that data. The end result is decreased maintainability and an increased
It has always been difficult to achieve strong encapsulation at the same time as distributing an application over physical tiers. If the data access code must run on an application server, but the object must run on the client or web server, we've typically created two different classes. One class is the business object itself that runs on the client, while the other contains the data access code and runs on the application server.
By definition, this breaks encapsulation, since we have two different objects (the business object and the data access object) that both externalize their data. Now, we can argue that this isn't too bad, because they're only externalizing their data to each otherand we might even argue that the objects are two
A better solution is to preserve encapsulation entirely by keeping all of the business logic for an entity in a single class. This can be accomplished if it's practical to move the object physically from client to server and back again. As we discussed in Chapter 1, we can achieve this by making our business objects unanchored, so that they move from machine to machine. However, this also implies that we have an object that is anchored on the application server, so that our client-side code can pass our objects to it.
This requirement is the purpose behind the server-side
object. It acts as the anchored object on the application server, receiving business objects from our
Once our object is physically on the server, it's the job of the server-side
to invoke the appropriate
On the client side, we also have a DataPortal object, which exists to simplify how the server-side DataPortal is called. Instead of writing the remoting code into each of our business objects, we can write it into a centralized, client-side DataPortal , and our business object code can use this more abstract mechanism to interact with the server-side DataPortal .