Deliverable: Scalability
Warning: !! This section of
the article has not been updated from my CSLA V1 article yet, as I
haven't had time to set up a virtual machine with .Net 2. The
concepts and deliverables are still the same, however the
configuration file settings may have changed with the new release.
An application based upon the CSLA framework has a number of
deployment options designed to meet the various scalability
challenges. A lot of work has been put into balancing the conflict
between scalability, and local UI performance objectives.
In a situation where there is no scalability requirement, our
application can be deployed so that the UI, business logic, and data
access logic are all serviced in a single Windows process resource,
inside the same PC. Our application can still have n logical tiers as
per sound programming practice, but while in this mode, the framework
incurs next to no runtime cost for it's inter-tier communications.
As scalability becomes an issue our application's logical tiers
can be deployed across n hardware tiers. All that is required is a
change to a configuration file, and then move the affected tier's dll
to the new platform. The framework has pre solved this challenge for
us.
By nature, a CSLA BO is a mobile object. CSLA makes
advanced use of .NET to transmit the BO between the logical tiers, in
the lowest overhead manner that is available, given our choice
regarding how the logical tiers have been arranged across any
hardware tiers.
A CSLA BO has a dual personality. It will contain the high level
functions that will be employed when it is being used inside the UI
logical tier. It will also contain any data access code that is
required when the object is being used within the framework's data
portal tier to access or update a database.

The
BO has no need to know how it is to be deployed, as the CSLA
framework has abstracted away all inter-tier communication functions.
To demonstrate this I have created a simple BO called BOTierLocation
whose only behaviour is that it has the capability to report back
where it is running from.
Being a WinForms application there is an exe file which is the UI,
and then there is also a dll which defines the BO. The CSLA framework
itself also contains various dlls to perform it's tasks. If I deploy
my demonstration application on a single machine, and then run it, I
see this display. This shows me that both the WinForms UI and the
framework's data portal are running within a single Windows process.
Next I will simulate deploying our application across another
tier. We will have the UI running on the user's PC, but have the BO
operating on a centralised application server to provide the BO's
behaviour, and to access any database server as required. For this
demonstration I will use the same application, without recompilation.
The only change I have made is to add the “PortalServer”
key to the run-time configuration file as follows. This change will
cause that part of the CSLA framework that our UI is interacting
with, to look for the data portal on the PC named “clone1”.
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<appSettings>
<add key="Authentication" value="Windows" />
<add key="PortalServer" value="http://localhost/DataPortalcs/DataPortal.rem" />
</appSettings>
</configuration>

As I don't have a server here, I have simulated the user's PC and
application server using Vmware Workstation. I have set up a VMware
team consisting of two PC's:
* Clone1 has .Net
and IIS installed. The BO dll and the framework are installed in an
IIS virtual directory named DataPortalcs
* Clone2 has .Net,
the CSLA framework, my BO dll, and the WinForms exe installed
I have run the WinForms executable upon Clone2. As you can see
from the diagram, my application is now successfully running across
both tiers. We can therefore easily modify our application to use a
centralised application server for our business objects, and thereby
greatly reduce the number of concurrent connections to our database
via connection pooling.
CSLA has shielded the programmers, of both the UI and the BO, from
the .NET Remoting plumbing complexity that is required to achieve
this situation.
Rocky has indicated in his web log that the .NET v2 of CSLA will
probably add web services, Enterprise Services and Indigo transport
options to current single option of .NET Remoting.
Now let us look at some of the source code that we have been using
here. Firstly we have the UI's Click event handler for the “Access
portal” button.. This action requests a new instance of our
BOTIierLocation object, and then used it's ServerName and ProcessID
properties to populate the lower of the two Textboxes. As you can see
the UI is completely unaware of the location of data portal, which is
acting in an Object Factory mode to create and deliver the requested
BO. It is unaware that it is dealing with a Proxy object which may be
on another machine.
private void button1_Click(object sender, System.EventArgs e)
{
/* create a new BO; in this case a simple read-only object whose
only behaviour is that it is able to describe the context
within which the data portal (data access layer) is running */
BOTierLocation ro = BOTierLocation.GetNewBOTierLocation();
// display the context
txbDataPortal.Text =
String.Format("Machine name = {0}\r\nProcess ID = {1}",
ro.ServerName, ro.ProcessID);
}
Finally we will look at the important sections of the code defining
our BOTierLocation class. I will ignore the following items as they
are not relevant to what I am demonstrating here:
it's ServerName and ProcessID properties,as these are just
standard property get accessors
it's overrides of the Object class' Equals, ToString and
GetHashCode methods
it's constructor (empty, and private so that the UI cannot
create our object without going through the data portal)
definition of the criteria class that would be used to
identify our BO in cases where we were creating, changing or
deleting it.
What we will look at is the GetNewBOTierLocation method used by
the UI, and the code that will be run by the data portal tier, which
as we have seen may be in-process with the UI, or may be hosted upon
a remote machine. Our BO can focus on just the business rules, and
doesn't become tangled up with the .Net plumbing required to achieve
this scalability capability. We get this capability because we have
descended from one of the CSLA frameworks classes (ReadOnlyBase on
this occasion).
namespace ExpertBusinessObjects.Library
{
[Serializable()]
public class BOTierLocation : ReadOnlyBase
{
// Declare state variables
private Guid _id = Guid.NewGuid();
private int _processID;
private string _machineName;
#region Business Properties and Methods
// snipped
#endregion
#region System.Object Overrides
// snipped
#endregion
#region Static methods
public static BOTierLocation GetNewBOTierLocation()
{
return (BOTierLocation)DataPortal.Fetch(new Criteria());
}
#endregion
#region Constructors
// snipped
#endregion
#region Criteria
// snipped
#endregion
#region Data Access
// called by DataPortal to load state, usually from the database
protected override void DataPortal_Fetch(object criteria)
{
_processID =
System.Diagnostics.Process.GetCurrentProcess().Id;
_machineName = Environment.MachineName;
}
#endregion
}
} |