Using CSLA .NET for Silverlight to Build Line-of-Business Applications

Using CSLA .NET for Silverlight to Build Line-of-Business Applications

he CSLA framework, written by Rockford Lhotka, has been around for over a decade. CSLA’s purpose is to give developers a solid framework to house business logic for applications. Microsoft .NET developers have adapted CSLA to new technologies as they emerge, and many developers use CSLA .NET heavily to construct robust, scalable .NET-based solutions supported on all Microsoft UI platforms, Windows, and the web. CSLA .NET for Silverlight follows that lead, letting developers create a Silverlight-compatible object-oriented business layer that abstracts and encapsulates your business logic and data, simplifying and standardizing business logic implementation, data validation, and user authorization within your objects. The goal is to provide an easy and consistent coding pattern by which you can encapsulate all your business logic within your object-oriented business layer. The result is a business layer that supports development of rich, interactive Silverlight applications.

CSLA .NET for Silverlight’s key features remain the same as in other versions: full support for Silverlight data binding, N-level undo, authorization/authentication features, validation rules, abstract data persistence, mobile objects that span physical boundaries to perform business functions, and multi-tier deployment model support.

Target Scenarios

You can use CSLA .NET for Silverlight to develop Silverlight-based scalable line-of-business applications. Because Silverlight applications run in a Web browser, these applications require an application server component.

CSLA .NET for Silverlight has two primary ways to interact with an application server, the most common of which will probably be the CSLA .NET for Silverlight remote data portal. In this scenario, the Silverlight client calls the data portal for all CRUD operations and the data portal invokes CSLA .NET components on the server. In this case, CSLA .NET for Silverlight-based applications will still use CSLA .NET functionality to implement the data portal and business objects will move between the client and server just like they do in .NET.

The other primary scenario uses the CSLA .NET for Silverlight local data portal. In this case, the Silverlight client calls the data portal, but the data access code runs on the Silverlight client. These data access methods typically make calls to an external service (for example a WCF service, ADO.NET Data Services, or traditional Web service) to get or update data.

Stereotypes

CSLA .NET for Silverlight supports the following standard CSLA business object stereotypes:

?
Figure 1. Solution Structure: Here’s how a CSLA .NET for Silverlight-based application looks in Visual Studio’s Solution Explorer.
  • Editable root
  • Editable child
  • Read-only root
  • Read-only child
  • Editable root list
  • Editable child list
  • Read-only root list
  • Read-only child list
  • Name/value list
  • Command
  • Dynamic root list
  • Dynamic root

CSLA .NET for Silverlight Example

You need a number of projects to implement a CSLA .NET for Silverlight solution (see Figure 1). The first project is a .NET class library (Rolodex.Business.Server) that shares business object class files with the Silverlight class library (Rolodex.Business.Client). You also need a Silverlight application project (Rolodex) that compiles into the Silverlight XAP file/executable assembly. Finally, you need a web project (Web) to host the Silverlight application. This project can, at the same time, host the CSLA .NET data portal application server components. Alternatively you can create a separate project to host the data portal (WcfHostWeb).

Editor’s Note: This article was first published in the November/December 2008 issue of CoDe Magazine, and is reprinted here by permission.

CLSA Business Objects in Detail

Business object stereotypes are at the heart of any CSLA application, whether Silverlight or .NET based. A key point of CSLA .NET for Silverlight is that all business objects are shared between the Silverlight client application and a .NET application (via the data portal). These are mobile objects and they travel across physical boundaries and runtimes. Any business object has sections that implement business functionality such as business logic, property declarations, validation and authorization rules, factory methods that call the data portal, and data access methods.

CSLA .NET for Silverlight simplifies and standardizes the implementation of business logic, validation, and authorization within your objects

Class Declaration

The standard way to declare a CSLA business object is:

   [Serializable]   public class Company : BusinessBase

You must inherit from a CSLA base class to get the rich functionality available in CSLA. All your objects must be marked with the Serializable attribute to enable mobile object functionality.

Property Declaration

A typical CSLA .NET for Silverlight property declaration looks like this:

   private static PropertyInfo    CompanyNameProperty = RegisterProperty(     new PropertyInfo("CompanyName",       "Company Name", string.Empty));      public string CompanyName     {    get { return GetProperty(CompanyNameProperty); }    set { SetProperty(CompanyNameProperty, value); }   }

As you can see, CSLA .NET for Silverlight simplifies property declaration. The RegisterProperty pattern should be familiar to anyone who has done any custom control creation with WPF; it is similar to the way dependency properties work. Registered properties in CSLA .NET for Silverlight provide the ability to manage backing fields for you. There are numerous advantages to that, including transfer of data through the data portal. Despite its deceptively simple syntax, SetProperty() performs a number of functions for the developer, such as running business and validation rules, verifying access rights based on authorization rules, maintaining object states (such as marking the object “dirty” when the property changes), and raising the PropertyChanged event to which the data binding is listening. All these capabilities are available out of the box.

Validation Rules

To supply validation rules, a developer must add them to the framework-supplied method:

   protected override void AddBusinessRules()     {     ValidationRules.AddRule(     Csla.Validation.CommonRules.StringRequired,      new Csla.Validation.RuleArgs(CompanyNameProperty));     ValidationRules.AddRule(     Csla.Validation.CommonRules.StringMaxLength,      new Csla.Validation.CommonRules.MaxLengthRuleArgs(     CompanyNameProperty, 50));    }

CSLA .NET for Silverlight has the same built-in validation rules as the full version of CSLA .NET, including string required, maximum and minimum string length, minimum and maximum numeric-field values, and more. In addition, developers can write and use an unlimited number of custom rules as long as they conform to a delegate declaration defined by CSLA: they must be functions that return a Boolean value.

Additionally, (new to CSLA 3.6), is the notion of asynchronous validation rules. If you create a rule that needs to make a call to a remote server you will want to make your rule asynchronous because Silverlight service calls are asynchronous. There is an asynchronous validation rule delegate in addition to the standard validation rule delegate; otherwise, the technique for creating asynchronous validation rules is the same.

Authorization Rules

Authorization rules work in much the same way as in standard CSLA?you simply specify what roles can perform which operations for a given business object:

   protected override void AddAuthorizationRules()   {      string[] canWrite = { "AdminUser", "RegularUser" };      string[] canRead = { "AdminUser", "RegularUser", "ReadOnlyUser" };      string[] admin = { "AdminUser" };      AuthorizationRules.AllowCreate(typeof(Company), admin);      AuthorizationRules.AllowDelete(typeof(Company), admin);      AuthorizationRules.AllowEdit(typeof(Company), canWrite);      AuthorizationRules.AllowGet(typeof(Company), canRead);      AuthorizationRules.AllowWrite(CompanyNameProperty, canWrite);      AuthorizationRules.AllowWrite(CompanyIdProperty, canWrite);      AuthorizationRules.AllowWrite(DateAddedProperty, canWrite);      AuthorizationRules.AllowRead(CompanyNameProperty, canRead);      AuthorizationRules.AllowRead(CompanyIdProperty, canRead);      AuthorizationRules.AllowRead(DateAddedProperty, canRead);   }

CSLA performs authorization against the current principal set in ApplicationContext.User. To create a principal for CSLA .NET for Silverlight you must create a principal business object:

   [Serializable]   public class RolodexPrincipal : BusinessPrincipalBase   { /* ... */ }

When a user logs in you simply fetch this principal like any other business object and set it to the current user of the ApplicationContext:

   private static void SetPrincipal  (Csla.Security.CslaIdentity identity)   {      RolodexPrincipal principal = new RolodexPrincipal(identity);      Csla.ApplicationContext.User = principal;   }

Factory Methods

The factory method is a standard pattern for exposing object creation and fetching to the consumer. In CSLA .NET for Silverlight, because all data access is asynchronous, rather than employing the standard system?passing criteria as parameters and returning the resulting object?the recommended pattern for creating factory methods is with a Continuation Passing Style (CPS). With this technique you first pass a delegate to a method that will be invoked when the asynchronous operation has completed, and then to your criteria parameters:

   public static void GetCompany(   int companyId,       EventHandler handler)   {      DataPortal dp = new DataPortal();      dp.FetchCompleted += handler;        dp.BeginFetch(new SingleCriteria(companyId));   }

Data Access Methods

To get data into your business object you must implement the various applicable DataPortal_XYZ methods. If you are using the remote data portal, you need to implement these methods only on the .NET server version of your business objects. To fetch a Customer object, for example, you would create a DataPortal_Fetch() method. You may override the base class’s DataPortal_Fetch() method or create a method that exactly matches the criteria object you passed into your DataPortal call in the factory method. CSLA will call the appropriate overload:

   protected void DataPortal_Fetch  (SingleCriteria criteria)   {      using (SqlConnection connection = new SqlConnection(         DataConnection.ConnectionString))      {         connection.Open();         /* Data Access Here */         LoadProperty(         CompanyIdProperty,  reader.GetInt32("CompanyID"));         LoadProperty(CompanyNameProperty,             reader.GetString("CompanyName"));         LoadProperty(DateAddedProperty,             reader.GetSmartDate("DateAdded"));          /* Load Children Here */      }   }

User Interface Support

CSLA has robust support for build rich user interfaces in Silverlight using CSLA’s data-binding capabilities and custom Silverlight controls and classes.

Data Binding

Data binding in Silverlight is almost syntactically identical to WPF. For example, to bind a TextBox to a company name, you bind its Text property to an underlying data source, while specifying the path to a target property as shown below:

                                                                                                     

The preceding code specifies only a path to the CompanyName property because the DataContext is set on the outer control (the Grid). It specifies the binding mode as TwoWay so as to propagate user changes to the underlying object.

The CslaDataProvider Class

As you probably noticed, the preceding code binds all the controls to a static resource called CompanyData. More specifically, it binds the grid to that resource, and then the controls specify only the property name to which they are bound. Here’s the CompanyData resource definition:

   
CSLA .NET for Silverlight provides many features, such as data binding, authorization business, and validation rules, flexible data access, and N-level undo

CslaDataProvider is a CSLA .NET for Silverlight framework control that serves as a UI wrapper for business objects, enabling simplified syntax in XAML and greatly reducing the need for code-behind to perform functions on this business object. This control can automatically load the data into the object (although in the example IsInitialLoadEnabled is set to false). You can also specify the object you would like to use. You have to do this using an assembly-qualified class name due to lack of support for x:Type markup extensions in Silverlight. You can also specify what method to call when creating a new object (CreateFactoryMethod) or filling the object with data (FetchFactoryMethod). You can also subscribe to events that the object raises. The DataProvider knows how to save changes or cancel user changes via Save and Cancel methods. Finally, it can work in conjunction with the InvokeMethod object to further reduce the need for code-behind, as you’ll see next.

The InvokeMethod Class

The InvokeMethod class is new in CSLA .NET for Silverlight. Its purpose is to simulate commanding, which is missing in Silverlight. You can attach InvokeMethod to a control, have it listen for a specific event, and invoke a specified method on another object in response to the event. Here’s an example:

   

The preceding example attaches an InvokeMethod object to the Save button. When a user clicks this button, the InvokeMethod invokes the Save method on CompanyData (the CslaDataProvider object). You can use InvokeMethod in other situations as well, invoking methods on arbitrary objects at run time. However, InvokeMethod integrates particularly well with CslaDataProvider, enabling/disabling controls based on the state of the data source. In the preceding example, SaveButton gets enabled only after a user has changed the data. Additionally, the IsEnabled property is bound to the CslaDataProvider’s CanSave property. As a result, the button is enabled only when the object is valid, and has pending changes.

The Property Status Control

The PropertyStatus control lets you display visual cues related to a particular property of your business object. Specifically, it can:

  • Display tool tips with messages for all broken validation rules.
  • Display a busy animation for any outstanding asynchronous operations.
  • Disable, or make read-only a control that is also bound to the same property.

Simply declare this control in your XAML like this:

   

The Object Status Control

This control’s purpose is to let a designer create storyboards based on a business object’s status. While controls such as MethodInvoke or the CslaDataSource give you ways to easily enable/disable controls through binding, the ObjectStatus control supports a broader range of interactivity by using the Visual State Manager (covered in more detail in a future article).

You’ve seen the basics of using CSLA .NET for Silverlight to develop business applications. To reiterate, the primary goal is to allow developers to focus on their business problem, not the complex technologies behind the scenes. Therefore, CSLA .NET for Silverlight provides features such as data binding, authorization business, and validation rules, flexible data access, and N-level undo that help developers create robust, feature-rich Silverlight applications.

CSLA can also neatly encapsulate business logic inside business objects, allowing them to be reused in other .NET applications, such as Windows Forms, WPF, or ASP.NET?with few or no code changes. The reverse is also true, because you can adapt existing CSLA .NET-based applications for Silverlight with minimal code changes. Follow these links to download all the source code used in the article and get more information on CSLA.NET and CSLA.NET for Silverlight.

devxblackblue

About Our Editorial Process

At DevX, we’re dedicated to tech entrepreneurship. Our team closely follows industry shifts, new products, AI breakthroughs, technology trends, and funding announcements. Articles undergo thorough editing to ensure accuracy and clarity, reflecting DevX’s style and supporting entrepreneurs in the tech sphere.

See our full editorial policy.

About Our Journalist