Download as pdf or txt
Download as pdf or txt
You are on page 1of 137

Using CSLA 4

Creating Business Objects

Rockford Lhotka
Using CSLA .NET 4: Creating Business Objects

Copyright © 2011-2012 by Marimer LLC

All rights reserved. No part of this work may be reproduced or transmitted in any form or by any
means, electronic or mechanical, including photocopying, recording, or by any information
storage or retrieval system, without the prior written permission of the copyright owner.

Trademarked names may appear in this book. Rather than use a trademark symbol with every
occurrence of a trademarked name, we use the names only in an editorial fashion and to the
benefit of the trademark owner, with no intention of infringement of the trademark.

Editor: Teresa Lhotka

The information in this book is distributed on an “as is” basis, without warranty. Although every
precaution has been taken in the preparation of this work, the author shall not have any liability
to any person or entity with respect to any loss or damage caused or alleged to be caused directly
or indirectly by the information contained in this work.

The source code for this book (CSLA 4 version 4.1.0) is available at
http://www.lhotka.net/cslanet.

Errata or other comments about this book should be emailed to errata@lhotka.net.

Revision: 1.1
Acknowledgements
Neither this book, nor CSLA 4, would have
been possible without support from Magenic.
Magenic is the premier .NET development
company in the US, and is a Microsoft Gold
Certified Partner.

You can reach Magenic at


http://www.magenic.com.

CSLA .NET has attracted a community of very


thoughtful, intelligent and dedicated people.
You can find many of them at
http://forums.lhotka.net.

The bug fixes and feature enhancements


described in this book come, in no small part,
through the encouragement and feedback
provided by this stellar community.

Thank you all!


About the Author
Rockford Lhotka is the author of more than 17 books on developing software using the Microsoft
platform and technologies. He is a Microsoft Regional Director and a Microsoft MVP. Rockford
speaks at many conferences and user groups around the world. He is the Chief Technology Officer
at Magenic (www.magenic.com), a company that specializes in planning, designing, building and
maintaining your enterprise’s most mission critical systems.
Contents
Introduction........................................................................................................................................................... 1
Organization of the Book ..........................................................................................................................................1
Framework Code and Samples ..................................................................................................................................1

Chapter 1: Key Object Concepts ............................................................................................................................. 3


Stereotypes ...............................................................................................................................................................3
Serialization ..............................................................................................................................................................4
Choosing Serializers .............................................................................................................................................5
Configuring CSLA .NET to use NetDataContractSerializer ...............................................................................5
Configuring CSLA .NET to use MobileFormatter .............................................................................................6
Object Lifetime ..........................................................................................................................................................6
Object Relationships .................................................................................................................................................6
Containment ........................................................................................................................................................7
Using ....................................................................................................................................................................7
Object Identity and Equality......................................................................................................................................8
Platform Differences in .NET and Silverlight .............................................................................................................9
Limitations on Reflection .....................................................................................................................................9
Asynchronous Server Access ..............................................................................................................................10
Threading ...........................................................................................................................................................11
Data Access ........................................................................................................................................................11
Property Declarations .............................................................................................................................................12
Basic CSLA 4 Property Concepts .........................................................................................................................13
Basic Property Implementation.....................................................................................................................13
Helper Methods ............................................................................................................................................14
RegisterProperty and PropertyInfo<T> .........................................................................................................14
Manual and Managed Backing Fields ............................................................................................................17
Properties and Stereotypes................................................................................................................................18
Types of Property Declaration ...........................................................................................................................18
Read-Write ....................................................................................................................................................19
Read-Write with No Rules .............................................................................................................................22
Read-Write with Value Conversion ...............................................................................................................23
Read-Only ......................................................................................................................................................25
Read-Only with Value Conversion .................................................................................................................25
Child Object Reference ..................................................................................................................................26
Child Object Reference with Lazy Loading ....................................................................................................27
Properties with Manual Backing Fields .........................................................................................................30
Inter-Graph Reference ..................................................................................................................................35
Using Reference ............................................................................................................................................35
Non-Generic LoadProperty Method ..............................................................................................................37
Method Declarations ..............................................................................................................................................37

Using CSLA 4: Creating Business Objects Page i


Copyright © 2012 Marimer LLC
Metastate ...............................................................................................................................................................37
Accessing Metastate ..........................................................................................................................................39
Public Properties ...........................................................................................................................................39
ITrackStatus Interface....................................................................................................................................40
INotifyBusy Interface .....................................................................................................................................40
INotifyChildChanged Interface ......................................................................................................................40
Data Binding ..................................................................................................................................................40
Basic Status ........................................................................................................................................................40
IsNew Property ..............................................................................................................................................40
IsDeleted Property ........................................................................................................................................41
IsSavable Property .........................................................................................................................................41
MarkDeleted and Delete Methods ................................................................................................................42
MarkNew Method .........................................................................................................................................42
MarkOld Method ...........................................................................................................................................42
Change Tracking .................................................................................................................................................43
IsDirty Property .............................................................................................................................................43
IsSelfDirty Property .......................................................................................................................................43
MarkClean Method .......................................................................................................................................44
PropertyHasChanged Method .......................................................................................................................44
MarkDirty Method ........................................................................................................................................44
Object Validity ....................................................................................................................................................45
IsValid Property .............................................................................................................................................45
IsSelfValid Property .......................................................................................................................................45
Busy Tracking .....................................................................................................................................................45
IsBusy Property..............................................................................................................................................45
IsSelfBusy Property ........................................................................................................................................46
IsPropertyBusy Method.................................................................................................................................46
BusyChanged Event .......................................................................................................................................46
MarkBusy Method .........................................................................................................................................46
MarkIdle Method ..........................................................................................................................................47

Chapter 2: Solution Structure .............................................................................................................................. 48


Project Types and Assembly References .................................................................................................................48
Combining Projects to Create Solutions ..................................................................................................................49
Reusing Business Assemblies Across Platforms .................................................................................................50
Controlling the Assembly and Namespace Names ........................................................................................51
Linking Files ...................................................................................................................................................52

Chapter 3: Object Stereotypes ............................................................................................................................. 55


Editable Objects ......................................................................................................................................................55
Editable Root and Child ......................................................................................................................................55
Editable Root and Child List ...............................................................................................................................59
Adding New Items .........................................................................................................................................60
Dynamic Root List and Dynamic Root ................................................................................................................63
Dynamic Root ................................................................................................................................................64
Dynamic Root List ..........................................................................................................................................64
Read-Only Objects ...................................................................................................................................................66
Read-Only Root and Child ..................................................................................................................................66
Read-Only Root and Child List ............................................................................................................................67
Name-Value List .................................................................................................................................................68

Using CSLA 4: Creating Business Objects Page ii


Copyright © 2012 Marimer LLC
Execution Objects ....................................................................................................................................................70
Command ...........................................................................................................................................................70
Unit of Work .......................................................................................................................................................72
Data Retrieval ................................................................................................................................................72
Data Update ..................................................................................................................................................74
Criteria Objects .......................................................................................................................................................75
Simple Criteria ....................................................................................................................................................75
Complex Criteria.................................................................................................................................................76
Using CriteriaBase .........................................................................................................................................76
Using BusinessBase .......................................................................................................................................77
LINQ Types ..............................................................................................................................................................77
LinqObservableCollection ..................................................................................................................................78
Windows Forms Types ............................................................................................................................................78
BusinessBindingListBase ....................................................................................................................................80
DynamicBindingListBase ....................................................................................................................................80
ReadOnlyBindingListBase ...................................................................................................................................80

Chapter 4: Business Rules .................................................................................................................................... 82


Business and Validation Rules .................................................................................................................................83
Associating Rules with Properties and Types .....................................................................................................84
Using DataAnnotations Attributes ................................................................................................................84
Using AddBusinessRules ................................................................................................................................84
Rule Priorities ................................................................................................................................................85
Short-Circuiting Rules ....................................................................................................................................86
Rule Sets ........................................................................................................................................................87
Executing Rules ..................................................................................................................................................88
Per-Property Rules ........................................................................................................................................88
Dependent Properties ...................................................................................................................................88
Per-Type Rules ...............................................................................................................................................90
Manually Executing Rules ..............................................................................................................................90
Executing Rules in Parent Objects .................................................................................................................91
Suppressing Rule Execution...........................................................................................................................91
Implementing Business and Validation Rules ....................................................................................................93
Structure of a Rule.........................................................................................................................................93
RuleContext Parameter .................................................................................................................................94
IBusinessRule Interface .................................................................................................................................96
BusinessRule Base Class ................................................................................................................................97
Rule State ......................................................................................................................................................99
Rule Chaining ...............................................................................................................................................100
Asynchronous Rules ....................................................................................................................................101
Implementing Business Rules...........................................................................................................................108
Using the Target Property ...........................................................................................................................109
Interacting with the Entire Object Graph ....................................................................................................110
Implementing Validation Rules ........................................................................................................................110
Broken Rules Collection ...............................................................................................................................110
Validation Rule Classes ................................................................................................................................111
DataAnnotations Attributes ........................................................................................................................112
Accessing Rule Information and Results ..........................................................................................................113
Get a List of Rules for a Type .......................................................................................................................114
Get Rule Results from an Object .................................................................................................................115

Using CSLA 4: Creating Business Objects Page iii


Copyright © 2012 Marimer LLC
Authorization Rules ...............................................................................................................................................117
Associating Rules with Properties and Types ...................................................................................................119
Using AddBusinessRules ..............................................................................................................................119
Using AddObjectAuthorizationRules ...........................................................................................................120
Rule Sets ......................................................................................................................................................121
Executing Rules ................................................................................................................................................121
Manually Executing Rules ............................................................................................................................122
Suppressing Rule Execution.........................................................................................................................123
Implementing Authorization Rules ..................................................................................................................124
Structure of a Rule.......................................................................................................................................124
AuthorizationContext Parameter ................................................................................................................125
IAuthorizationRule Interface .......................................................................................................................126
AuthorizationRule Class...............................................................................................................................127
Rule State ....................................................................................................................................................127

Conclusion ......................................................................................................................................................... 128

Using CSLA 4: Creating Business Objects Page iv


Copyright © 2012 Marimer LLC
List of Tables
Table 1. Stereotypes directly supported by CSLA 4 4
Table 2. Kinds of object relationship 7
Table 3. Scenarios where reflection limitations affect code 10
Table 4. Asynchronous features in CSLA 4 10
Table 5. Property getter and setter helper methods 14
Table 6. Elements defined by IPropertyInfo in Csla.Core 16
Table 7. Types of property declaration supported by CSLA 4 19
Table 8. Types directly serialized by MobileFormatter 33
Table 9. Serialization base classes in Csla.Core 34
Table 10. Metastate properties of CSLA .NET business objects 38
Table 11. Events raised by CSLA .NET business objects 39
Table 12. Common project types and related CSLA assembly references 48
Table 13. Typical projects in a WPF Application 49
Table 14. Typical proejcts in a 4-tier Silverlight Application 50
Table 15. Execution sequence of a command object 71
Table 16. Collection types and UI technologies 79
Table 17. Types of business rule supported by CSLA 4 82
Table 18. Methods used to manually execute rules 90
Table 19. Techniques for suppressing business rule execution 93
Table 20. Members provided by the RuleContext type 95
Table 21. Members defined in IBusinessRule interface 96
Table 22. Examples of rule:// URI values 97
Table 23. Properties available on a BrokenRule object 116
Table 24. Properties available on a BrokenRulesNode object 117
Table 25. Members defined by the AuthorizationContext type 125
Table 26. Members defined by the IAuthorizationRule interface 126

List of Figures
Figure 1. Process followed when setting a property value ........................................................... 21
Figure 2. Setting the assembly and namespace names in a .NET project ..................................... 51
Figure 3. Setting the assembly and namespace names in a Silverlight project ............................. 51
Figure 4. Setting the assembly and namespace names in a Windows Phone project ................... 52
Figure 5. Class library containing code files ................................................................................ 52
Figure 6. Add an existing item ...................................................................................................... 53
Figure 7. Adding files as a link ..................................................................................................... 53
Figure 8. Project containing linked files ....................................................................................... 54

Using CSLA 4: Creating Business Objects Page v


Copyright © 2012 Marimer LLC
Introduction
Welcome to Using CSLA 4: Creating Business Objects.
This book will provide you with the information necessary to use the CSLA .NET framework to
create the business domain objects that make up a business layer for your application. These
domain objects encapsulate behavior and contain the state necessary to implement that behavior.
In this context, behavior includes business rules, validation rules, and authorization rules, along with
public properties that provide access to select elements of the object’s state.
This book is part of a multi-part book series, consisting of several related ebooks. While each
ebook is separate, they are designed to work together to provide information about CSLA 4. This
book series will show you how to use the CSLA framework to build powerful and scalable
applications for Windows, Silverlight and the web.
This book builds on the information provided in the Using CSLA 4: CSLA .NET Overview ebook. It
is assumed that you have an understanding of the content from that ebook.

Organization of the Book


This ebook is the second in a series of related ebooks that together comprise the Using CSLA 4
book. Each ebook is separate, but they are designed to work together in a flexible manner so you
can get exactly the information you need for your application or project. All subsequent ebooks in
the series assume you have read the first two ebooks: Using CSLA 4: CSLA .NET Overview and Using
CSLA 4: Creating Business Objects (this book).
This book walks through the major base classes provided by the CSLA .NET framework. Each base
class is designed to support one or more object stereotypes, or basic types of business object useful
in most business applications. The base classes provide functionality you will use when building
business classes, including:

 Standardized property declarations


 Authorization rules
 Validation rules
 Business rules
 Metastate management
 Interaction with child and parent objects
 Interaction with objects outside the current object graph

By the end of this book you will understand the base classes, their related stereotypes and the
primary features of each base class supporting these areas of functionality.

Framework Code and Samples


The CSLA .NET framework and related code samples are available from the download page at:

Using CSLA 4: Creating Business Objects Page 1


Rev 1.1
http://www.lhotka.net/cslanet/download.aspx
This ebook uses CSLA 4 version 4.1, and I may refer to samples available in the standard Samples
download for CSLA .NET.
Additionally, in the Support folder provided as part of the CSLA 4 installation you will find a
Templates folder that contains very basic sample code illustrating the structure of each business
object stereotype described in this ebook.
Any code samples unique to this ebook will be included as a separate download available from
http://download.lhotka.net
This is also where you will have downloaded this ebook.

Using CSLA 4: Creating Business Objects Page 2


Rev 1.1
Chapter 1:
Key Object Concepts
Object-oriented design and programming are large topics, and this book is not a comprehensive
discussion of OOD or OOP. All the same, I will be using some key concepts throughout this book,
and it is important to ensure we have a shared understanding of these concepts and the terms I’ll
be using.

Stereotypes
Object-oriented design and programming involve the idea of taking similar concepts and
implementations and grouping them together into classes and stereotypes. You know about classes,
they are bits of code that organize related behaviors together so you can create individual instances
of those classes. Stereotypes are a broader concept that group together broad types of behavior.
Not necessarily specific behaviors, but specific types of behavior.
For example, a class might implement a specific business rule, and all instances of that class
(objects) have that rule. A stereotype is broader, suggesting that there’s a type of class that can
implement rules. So any class that has a rule is part of this “type that has rules” stereotype.
Good object-oriented design relies on stereotypes to help organize such broad concepts into
classes, allowing developers to combine those classes through composition, inheritance, or other
techniques into reusable and comprehensible types.
CSLA .NET relies on this concept of a stereotype to help define how it supports the creation of
powerful and flexible business domain objects that compose a business layer. The stereotypes
directly supported by CSLA 4 are listed in Table 1.

Stereotype Description Base Class


Editable root Object containing read-write properties; BusinessBase<T>
object can be retrieved/stored directly to
database.
Editable child Object containing read-write properties; BusinessBase<T>
object is contained within another object
and can not be retrieved/stored directly
to database.
Editable root list List object containing editable child BusinessListBase<T,C>
objects; list can be retrieved/stored BusinessBindingListBase<T,C>
directly to database.
Editable child list List object containing editable child BusinessListBase<T,C>
objects; list is contained within another BusinessBindingListBase<T,C>
object and can not be retrieved/stored
directly to database.
Dynamic root list List object containing editable root DynamicListBase<C>
objects; list is retrieved directly from DynamicBindingListBase<C>
database.
Using CSLA 4: Creating Business Objects Page 3
Rev 1.1
Command Object that executes a command on the CommandBase<T>
application server and reports back with
the results.
Unit of Work Object that combines operations against ReadOnlyBase<T> or
several other business objects. CommandBase<T>

Read-only root Object containing read-only properties; ReadOnlyBase<T>


object can be retrieved directly from
database.
Read-only child Object containing read-only properties; ReadOnlyBase<T>
object is contained within another object
and can not be retrieved directly from
database.
Read-only root list List containing read-only child objects; list ReadOnlyListBase<T,C>
can be retrieved directly from database. ReadOnlyBindingListBase<T,C>

Read-only child list List containing read-only child objects; list ReadOnlyListBase<T,C>
is contained within another object and ReadOnlyBindingListBase<T,C>
can not be retrieved directly from
database.
Name/value list List object containing read-only NameValueListBase<K,V>
name/value objects.

Table 1. Stereotypes directly supported by CSLA 4


I will discuss each of these stereotypes in detail in Chapter 3, but first I’ll continue to cover some
other key concepts.

Serialization
All business domain objects created for use with CSLA .NET must be serializable. The term
serializable means that the .NET and CSLA .NET frameworks are allowed to pull the field values
(even if not public) from a business object instance, and then use those field values to create an
exact clone of the original object, either on the same computer or on a computer across the
network.
This serialization, or cloning, is required by the mobile object concept I discussed in the Using
CSLA 4: CSLA .NET Overview ebook. Because mobile objects are a central feature of CSLA .NET, it
should make sense that all business types must be serializable to work with CSLA .NET.
The .NET framework has numerous types called serializers or formatters that clone object
graphs. Only two are capable of creating true clones of objects: the BinaryFormatter and the
NetDataContractSerializer (NDCS).

Silverlight and WP7 have no serializers that can create true clones, so CSLA .NET includes the
MobileFormatter, which provides the necessary functionality on Silverlight, WP7 and .NET.

In all cases, to be serializable, you must apply an attribute on your business class to give the
runtime permission to serialize your objects. Normally, this is the Serializable attribute.

Using CSLA 4: Creating Business Objects Page 4


Rev 1.1
[Serializable]
public class CustomerEdit : BusinessBase<CustomerEdit>

When using the NDCS, you can choose to use the DataContract and DataMember attributes over
the Serializable attribute. I recommend against this, because it prevents the use of the
BinaryFormatter or MobileFormatter. Even worse, you must remember to apply the DataMember
attribute on every single field declaration in your business class or you won’t get a complete clone
of the object. This “opt-in” technique is great for creating public service APIs, but is extra manual
work when creating business objects.
Later in this ebook, I’ll discuss the recommended property declaration and implementation
syntax for use in business types. That syntax is connected to serialization, and specifically, to the
way the MobileFormatter serializer works.
Whereas the BinaryFormatter and NDCS are able to use reflection to get and set non-public
field values in your objects, that type of reflection is prohibited in Silverlight for security reasons.
This is the reason those serializers don’t exist in Silverlight.
The MobileFormatter serializer avoids this issue by not using reflection, and instead relying on
active participation from each object to get and set the field values. CSLA .NET includes several base
class types that mostly automate this entire process, so you don’t have to worry about serialization.
As I’ll discuss later, you can choose to manually declare your own private fields for your
property values. In that case, you assume responsibility for overriding methods to get and set those
field values for serialization.

Choosing Serializers
When running on the .NET platform, the BinaryFormatter is used for serialization by default. When
running on Silverlight or WP7 (or if a .NET application server is interacting with a Silverlight client),
the MobileFormatter is used for serialization.
The MobileFormatter is the only option for Silverlight and WP7 applications.
For .NET applications you can choose between the three serializers through configuration.

Configuring CSLA .NET to use NetDataContractSerializer


For pure .NET applications you can choose to force CSLA .NET to use the NDCS instead of the
BinaryFormatter.

I recommend that you only configure CSLA .NET to use the NDCS if you use the
DataContract attribute instead of the Serializable attribute in your business
classes. Because I don’t recommend using the DataContract attribute, I generally
don’t recommend forcing the use of NDCS.

To configure CSLA .NET to use the NDCS you must add an element to the appSettings of your
app.config or web.config file:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<appSettings>
<add key="CslaSerializationFormatter" value="NetDataContractSerializer"/>

Using CSLA 4: Creating Business Objects Page 5


Rev 1.1
This will cause both the clone and n-level undo implementations in CSLA .NET to use NDCS. The
result is that you can use the DataContract attribute instead of, or in combination with, the
Serializable attribute in your business classes.

The important thing to remember is that all business classes must use Serializable for
DataContract to work with CSLA .NET. Throughout the rest of the book I’ll assume the use of the
Serializable attribute.

Configuring CSLA .NET to use MobileFormatter


Similarly, you can specify that CSLA .NET should use its own MobileFormatter instead of the
BinaryFormatter for all serialization, even for pure .NET applications. This is done with the
following configuration in your app.config or web.config file:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<appSettings>
<add key="CslaSerializationFormatter" value="MobileFormatter"/>

Normally the BinaryFormatter is a faster and more efficient serializer, so you shouldn’t override
the default. That said, the MobileFormatter avoids the use of reflection and so it may work in
medium trust environments where the BinaryFormatter is disallowed.
Again, I recommend not overriding the default configuration of the serializer in most application
scenarios.

Object Lifetime
Within the .NET framework all object instances have a lifetime. Typically an object is created using
the new keyword, and it is removed from memory by the .NET garbage collector some time after all
references to the object have been removed.
Business objects created using CSLA .NET often have a slightly more complex lifetime, because it
is assumed that these objects often contain data that must be retrieved from a database and later
saved into that database. The Using CSLA 4: Data Access ebook will cover these processes in detail.
For now you should understand that most business objects are created using the data portal, not
the new keyword. This allows CSLA .NET to help you manage the object’s lifetime, including
initializing the object’s state and metastate, as I’ll discuss later in this ebook.

Object Relationships
An object is a specific instance of a class, or type. Objects can have properties that refer to other
objects, creating a relationship between those two objects. It is important to understand that there
are different kinds of relationship that can exist between objects. Table 2 lists some important kinds
of relationship.

Relationship Description
Containment One object contains another object, such that the contained
object is part of the containing object. This is often referred to as
a parent-child relationship, because the child is part of the
parent.
Using CSLA 4: Creating Business Objects Page 6
Rev 1.1
Using One object uses the behaviors of another object, collaboring with
that object to accomplish some end goal. In this type of
relationship the objects are separate and independent, and
neither contains the other.

Table 2. Kinds of object relationship


The distinction here is important, and both types of relationship are very common in business
applications.

Containment
For example, an OrderEdit object contains a LineItems collection, which in turn contains
LineItemEdit objects. These are all containment relationships, and all these objects together form
something called an object graph.
An object graph is a family of related objects that directly rely on each other to implement their
respective behaviors. In this example, the OrderEdit object may calculate a TotalAmount value, and
that can only be done given access to the LineItemEdit objects it contains.
There are some important terms used to describe the objects in a containment relationship:
parent and child.
A parent object is an object that contains other objects. A child object is an object that is
contained within a parent object. It is important to realize that an object can be both a parent and a
child at the same time.
For example, consider that the LineItemEdit object could contain a LineItemDetails collection
of LineItemDetailEdit objects. In that case the LineItemEdit object is a child of LineItems, but is
also a parent.
A parent object that is not a child is called a root object. A root object is special, because it is the
top of the object graph. It is the one object that isn’t contained within another object, and so it is
the root of the object graph.

Using
A using relationship is quite different. For example, each LineItemEdit object might need to
calculate a tax on its price. But the concept of calculating a tax can vary from country to country,
and between provinces and states. Rather than embedding the tax calculation in the LineItemEdit
class, it is better to have a separate TaxCalculator type, allowing different implementations for
different geographic settings.
In this case the LineItemEdit objects might use a TaxCalculator to calculate the tax, but
there’s no way you could argue that the TaxCalculator is a child of a LineItemEdit object.
Not only is there an important conceptual difference here, but the actual code that implements
such relationships is different, as you’ll see when I walk through the implementation of the various
stereotypes and show how they interact.

Using CSLA 4: Creating Business Objects Page 7


Rev 1.1
Object Identity and Equality
Each object is a unique instance of a type, and so it has an identity. In fact, objects have more than
one “identity”, which can be confusing.
The most obvious type of object identity is that the object consumes physical memory in your
computer, and any variable or field referring to that object is a pointer to that area of memory. You
can find out if two objects are literally the same object in memory with the ReferenceEquals
method:
bool result = ReferenceEquals(a, b);

If result is true then you know that the two fields are pointing to the same object in memory.
You can also ask if two objects are equal to each other, but this is a much more complex
question. Obviously an object instance is always equal to itself, but what if you have two different
instances (and therefore consume different memory), but which share exactly the same public
property values?
Such objects might be considered equal, but suppose they have different private field values,
even though their public properties match?
Your application might need to apply a different definition of equality from other applications for
various reasons, and so the .NET framework allows you to override the Equals method in your
classes, and to implement the IEquatable interface.
Prior to .NET 3.0, this was fairly common practice. Now, WPF imposes some very severe
restrictions on equality, at least for items contained within collections. For collections to function
properly when bound to any WPF UI elements, the items in a collection can implement only a
couple forms of equality:

 Reference equality
 100% property and field equality between both objects

For all practical purposes this means that you should avoid overriding Equals, because the
default implementation is reference equalty.
This is important for CSLA .NET developers, because earlier versions of CSLA .NET enabled the
use of something called logical equality, where CLSA .NET made it relatively easy for you to override
Equals by implementing a method called GetIdValue in your business classes.

You should avoid overriding GetIdValue, as it is now considered deprecated and will
be removed in a future version of CSLA .NET.

CSLA .NET 3.0 and higher doesn’t support logical equality. The GetIdValue method exists only
for backward compatibility.

Using CSLA 4: Creating Business Objects Page 8


Rev 1.1
Platform Differences in .NET and Silverlight
It is important to understand that Silverlight is basically a subset of .NET. While not a true subset, it
is helpful to think about Silverlight andWP7 as having most of the important parts of .NET, plus a
few extra features.
There are a couple areas where the differences between the platforms will cause direct
differences in your business class code.

 Limitations on reflection
 Asyncronous server access
 Threading
 Data Access

I’ll discuss these differences here, and you’ll see examples of them in Chapter 3 as I walk through
each business object stereotype.

Limitations on Reflection
On the .NET platform reflection can be used to do many things, even interacting with non-public
members of an object. For example, you can use reflection to get or set private field values in an
object, or invoke a private method, or even create an instance of an object that has no public
constructors.
The .NET and CSLA .NET frameworks make use of these capabilities to do things like serialize
objects and make dynamic method calls. The CSLA .NET framework also uses reflection to get
information about business objects, such as retrieving a list of the object’s properties.
On the Silverlight and WP7 platforms reflection is restricted for security reasons. It is not
possible to use reflection to interact with non-public members of an object.

You can use reflection to interact with non-public members in your specific class.
Not in a subclass or base class, just your class. And certainly not in other types,
which prevents reflection from being useful in any scenario required by CSLA .NET.

Starting with CSLA .NET 3.6 the framework has included features to avoid and minimize the use
of reflection so the framework could support Silverlight 2 and higher. Table 3 lists some specific
places this affects your code.

Scenario Description
Property implementation CSLA .NET supports two basic ways to implement properties. The
concept of managed backing fields (discussed later) allows
automatic serialization of objects without using reflection.
Member scope In CSLA .NET code for .NET, many members can be private,
including the PropertyInfo<T> fields, data portal methods, and
the AddObjectAuthorizationRules method. In Silverlight
these must be public, otherwise CSLA .NET won’t be able to
discover or interact with these members and your business
Using CSLA 4: Creating Business Objects Page 9
Rev 1.1
objects won’t function correctly.
Constructors In CSLA .NET code for .NET I used to recommend that all business
classes have a non-public default constructor. The idea was to
remind users of the business class that they should use factory
methods, not the new keyword, to create instance of the type. In
Silverlight you must supply a default public constructor for
serialization to function.

Table 3. Scenarios where reflection limitations affect code


Because my intent is to have CSLA 4 support .NET, Silverlight and WP7 equally, I typically write
my business classes so they work on Silverlight. If they work on Silverlight, they’ll also work on .NET.
This means that I typically have a public default constructor, and all my PropertyInfo<T> fields
and other members listed in Table 3 are public.

Asynchronous Server Access


Most developers build applications assuming synchronous access to servers. When you use
ADO.NET to get data from a database, this is typically a synchronous call. When you use WCF to call
a service on an application server, this is typically a synchronous call.
Silverlight specifically requires that all server calls be asynchronous. This is because the Silverlight
runtime’s UI thread is the browser’s UI thread, and blocking that thread would block the entire
browser hosting Silverlight. That’d obviously generate a lot of negative feelings from end users
every time they used Silverlight, so Microsoft chose to require that all server interactions be
asynchronous, thus making it very hard for developers to accidentally block the UI thread and lock
up the browser.
The impact of all server interactions being async is substantial. It affects the way the data portal
works, because all calls to an application server are async. Even more, it affects how business rules
work, because some business rules need to interact with an application server. This is where the
idea of async business rules comes into the picture. If an object or property is executing an async
operation, and we don’t yet know the result, that object or property is in an indeterminate state.
CSLA 4 supports several asynchronous features as listed in Table 4.

Feature Description
Asynchronous data portal The data portal can be invoked synchronously or asynchronously
on .NET, and only asynchronously on Silverlight and WP7.
Asynchronous business rules Business and validation rules can be synchronous or
asynchronous. You should use asynchronous rules if your rule
needs to interact with the data portal or another object’s factory
methods in an async manner.
Busy status tracking Business objects have properties such as IsBusy and
IsSelfBusy that indicate whether the object (or one of its
properties) is currently executing an async operation.

Table 4. Asynchronous features in CSLA 4

Using CSLA 4: Creating Business Objects Page 10


Rev 1.1
I typically always implement async factory methods in my classes, and implement synchronous
factory methods only for the .NET platform. To do this, I use a compiler directive so the
synchronous code doesn’t compile for Silverlight. For example:
#if !SILVERLIGHT
// .NET-only code goes here
#endif

You should be aware that asynchronous operations are usually beneficial for any smart client
applications, including Silverlight, WPF, WP7, and Windows Forms. The primary benefit comes
through the fact that interactions with the server don’t lock up the UI, so the user has a better
overall experience.
That said, you should keep in mind that asynchronous operations make web development more
complex. This is because each web request is a non-interactive request from the browser that
normally runs on a single thread. It is critical that this primary thread not complete its work until
any async operations are complete, and that doesn’t happen automatically. This means you need to
write your own synchronization code to prevent that main thread from completing before all your
async operations complete. This leads to complexity, so I recommend avoiding the use of async
operations in ASP.NET applications as a general rule.

Threading
Threading is closely related to asynchronous operations, because the completion callback from a
normal async operation in .NET normally occurs on a background thread. You are responsible for
moving that callback to the UI thread before interacting with any UI objects, or objects that are data
bound to the UI.
Silverlight and WP7 avoid this complexity by automatically shifting completion callback calls to
the UI thread for you. This is a pretty significant difference between the .NET and Silverlight
platforms.
CSLA 4 helps you avoid confusion and complexity by also automatically shifting completion
callback calls from the data portal and async business rules to the UI thread for you. This means
that when using the async features of CSLA 4 you shouldn’t normally have to worry about
marshaling calls to the UI thread, as all completion callbacks are already on the UI thread.

The exception to this is in a console application, where .NET doesn’t provide a


synchronization context, so it isn’t possible to automatically marshal calls onto the
UI thread.

In Chapter 4, I’ll discuss asynchronous business rules in more detail, including a discussion of
where you can write code that will run on a background thread, and where your code is
automatically running on the UI thread.

Data Access
Silverlight has no data access API such as ADO.NET, and so it is not possible to write typical data
access code in Silverlight. You can use simple files for data storage through the isolated storage API
in Silverlight, but a typical Silverlight application will either use the data portal to interact with a
remote application server, or will make remote service calls to a service API by using WCF.
Using CSLA 4: Creating Business Objects Page 11
Rev 1.1
I’ll discuss data access in more detail in the Using CSLA 4: Data Access ebook. What is important
to understand right now, is that any data access code you might write in your business classes
needs to be wrapped in a compiler directive so the classes aren’t built on the Silverlight or WP7
platforms:
#if !SILVERLIGHT
// .NET-only data access code goes here
#endif

CSLA 4 tries to abstract the differences between the .NET and Silverlight platforms. Where this
isn’t possible, you will need to accommodate the differences in your own code, often using the
compiler directive strategy I’ve just discussed.

Property Declarations
Any .NET developer knows how to declare a standard property using the long and short syntax
available in C# or VB. For example:
public int MyNumber { get; set; }

private string _myText;


public string MyText
{
get
{
return _myText;
}
set
{
_myText = value;
}
}

For simplistic coding scenarios, this code can work fine. The story is very different if you are
creating business objects that support data binding, business rules, validation and authorization. In
that case, property declarations can become much more complex.
As an example, before returning a value in the property getter, you should check to see if the
user is authorized to see this value. Similarly, in the property setter you should do all the following:

 See if the user is authorized to change the value


 See if the new value is different from the existing value
 Raise the PropertyChanging event
 Record the new value
 Run any business and validation rules associated with this property
 Run any business and validation rules associated with related properties
 Mark the object as having been changed
 Raise the PropertyChanged event (using the correct behavior for Windows Forms or other
UI environments as appropriate)

Using CSLA 4: Creating Business Objects Page 12


Rev 1.1
All of a sudden declaring a property isn’t so simple anymore. Writing all the code to support
these behaviors into every property declaration results in huge class files that are hard to read and
hard to maintain.

Basic CSLA 4 Property Concepts


CSLA 4 provides several more abstract concepts to simplify the declaration and implementation of
properties and the associated fields that contain the property values. The idea behind these
concepts is to support the behaviors required to implement a powerful property, without forcing
the business developer to always deal with the related complexity.
These concepts include a standardized property declaration syntax that includes property
metadata description and helper methods that abstract most of the complex behaviors.
Additionally, it is possible to implement properties that use private backing fields, or allow CSLA
.NET to automatically manage the value of each property. Some properties reference other objects,
implementing containment or using relationships and there are specific property declarations to
support those scenarios.

Basic Property Implementation


For example, to avoid the complexity of implementing a setter as described earlier, CSLA 4 offers an
alternative, by providing a more concise and abstract syntax for property declaration. This syntax
includes the declaration of a static field that contains metadata about the property (helping to
miminize or eliminate the use of reflection) and helper methods that encapsulate the authorization,
validation and other behaviors I listed.
As a result, a typical read-write property looks like this:
public static readonly PropertyInfo<string> MyTextProperty =
RegisterProperty<string>(c => c.MyText);
public string MyText
{
get { return GetProperty(MyTextProperty); }
set { SetProperty(MyTextProperty, value); }
}

The GetProperty method checks authorization to make sure the current user is allowed to see
the value before returning the value.
The SetProperty method does a lot more, including:

 Checks authorization to make sure the current user is allowed to change the value
 Ensures the new value is different from the existing value
 Raises the PropetyChanging event
 Records the new value
 Runs any business and validation rules associated with this property
 Runs any business and validation rules associated with related properties
 Marks the object as having been changed
 Raises the PropertyChanged event (using the correct behavior for Windows Forms or other
UI environments as appropriate)
Using CSLA 4: Creating Business Objects Page 13
Rev 1.1
In short, all the behaviors you’d otherwise have to implement by hand are encapsulated in the
GetProperty and SetProperty helper methods.

Helper Methods
I’ve already mentioned the GetProperty and SetProperty helper methods. There are several
additional helper methods you’ll need to use to implement all the different property
implementation options. These are listed in Table 5.

Method Description
GetProperty Gets a property value, first checking authorization rules
ReadProperty Gets a property value without checking any authorization rules
SetProperty Sets a property value performing all processing as discussed in
the previous section in this chapter (running business rules, etc.)
LoadProperty Sets a property value without checking any rules, raising any
events or marking the object as having been changed
GetPropertyConvert Gets a property value, first checking authorization rules and
converting the backing field value to the appropriate property
value type
ReadPropertyConvert Gets a property value without checking any authorization rules
and converting the backing field value to the appropriate
property value type
SetPropertyConvert Sets a property value performing all processing as discussed in
the previous section in this chapter (running business rules, etc.)
and converting the new property value to the appropriate
backing field type
LoadPropertyConvert Sets a property value without checking any rules, raising any
events or marking the object as having been changed and
converting the new property value to the appropriate backing
field type

Table 5. Property getter and setter helper methods


You’ll see how these helper methods are used as I discuss the different types of property
declaration supported in the framework.

RegisterProperty and PropertyInfo<T>


I briefly mentioned a static field containing metadata about a property; its purpose being to
minimize or eliminate the use of reflection. It also eliminates the need to use any string literal
values to represent the name of a property by providing a strongly typed token that represents the
property name.
This static field is declared for any CSLA style property:
public static readonly PropertyInfo<string> MyTextProperty =
RegisterProperty<string>(c => c.MyText);

Using CSLA 4: Creating Business Objects Page 14


Rev 1.1
There are two key elements at work here.
First, there’s the RegisterProperty method that is registering the property metadata with the
CSLA .NET property management subsystem (often referred to as the field manager).
Second, there’s the PropertyInfo<T> type that is storing the property metadata.
Registering a property’s metadata is a requirement for many features of CSLA 4, and you should
expect to register your properties using this technique.

RegisterProperty
The RegisterProperty method is responsible for registering metadata about a property. This
method has numerous overloads to accommodate different property declaration scenarios, and
you’ll see them in use as I walk through each type of property declaration.
Ultimately, RegisterProperty does two basic things.
First, it gets or creates an IPropertyInfo (from the Csla.Core namespace) instance that
contains the property metadata. Typically, this is a PropertyInfo<T> instance as shown in this
example. That value is returned as a result of the RegisterProperty method, so you can store the
value in a static field for use throughout your code.
Second, this IPropertyInfo instance is added to a static data structure maintained by CSLA
.NET so it is possible for the framework (and therefore your code) to get a list of all the properties
registered for a business class type without the need for reflection.
Avoiding reflection is often a good idea for performance reasons, and that’s a nice side-benefit in
this case. But the real value here is that this mechanism allows CSLA 4 to automatically serialize and
deserialize objects on the Silverlight and WP7 platforms where reflection has restrictions that make
it otherwise impractical to create a normal .NET serialization component.
From a day to day practical perspective, the benefit to registering properties like this is that your
business code has easy access to a static field that represents the property. This makes it easy to
use metadata about the property, or to refer to the property without resorting to the use of the
property name in string form.
So you can use MyTextProperty instead of “MyText” to talk about the MyText property. This
increases the maintainability of your code, because standard refactoring tools will automatically
rename the strongly typed metadata field, but wouldn’t rename any string literal names referring to
your properties.

PropertyInfo<T> and IPropertyInfo


As I discussed, the RegisterProperty method has numerous overloads, some of which accept a
pre-created IPropertyInfo (usually a PropertyInfo<T>), or the RegisterProperty method will
create an instance of PropertyInfo<T> for you.
The important type is IPropertyInfo from the Csla.Core namespace, because that’s the base
type required by the field manager and other parts of CSLA .NET. That said, the generic
PropertyInfo<T> is more efficient because it is strongly typed, and it is used whenever possible for
performance reasons.

Using CSLA 4: Creating Business Objects Page 15


Rev 1.1
Either way, the IPropertyInfo or PropertyInfo<T> field is what contains the metadata about
each of your properties. Table 6 lists the elements defined by IPropertyInfo.

Element Description
Name Gets the name of the property (or method)
Type Gets the type of the property
FriendlyName Gets the human readable friendly display name of the property
DefaultValue Gets the default value for a new instance of the property
NewFieldData Gets a new field data container for the property; for advanced
scenarios only
RelationshipType Gets the relationship type for the property
Index Gets the index position of the property in the internal field
manager data store; for internal CSLA .NET use only

Table 6. Elements defined by IPropertyInfo in Csla.Core


Most of these elements are intended for use by CSLA .NET or your code. For example, you might
use the FriendlyName property to get a human readable display name for the property, and then
use that value for a label on a form.
The Index element is specifically intended for internal use by CSLA .NET itself. In some cases
CSLA .NET will manage your property’s field value on your behalf, and this Index value is used to
provide fast access to the field value within internal CSLA .NET data structures. You should avoid
using this value for anything within your application code.
The DefaultValue property should only be used for value types or immutable reference types
such as the string type. The DefaultValue property is set when the RegisterProperty method is
called, and that occurs exactly one time per AppDomain. This means the default value is shared
across all instances of the business class.
You can not use the DefaultValue property to set a reference to a CSLA .NET business type,
because the resulting default value would end up having numerous parent objects. A CSLA .NET
business object can have exactly one parent object, and attempting to reuse an object as a child of
numerous parent objects will result in runtime errors that can be hard to detect and resolve.
Because this is all interface based, and PropertyInfo<T> is not sealed, it is possible for you to
extend the metadata stored for each property. This is an advanced scenario not covered in this
book, but if you do wish to maintain extra metadata about each of your properties it is possible.
The NewFieldData method supports that advanced scenario, allowing you to override the
behavior that creates a PropertyInfo<T> so you can create your own IPropertyInfo or your own
subclass of PropertyInfo<T> when that value is required by the framework.
Again, you will typically use the standard metadata fields, including the FriendlyName and Name
properties, which provide valuable metadata about each property.

Using CSLA 4: Creating Business Objects Page 16


Rev 1.1
Manual and Managed Backing Fields
Traditional property declarations have what is called a private backing field or a manual backing
field. For example:
private string _myText;
public string MyText
{
get
{
return _myText;
}
set
{
_myText = value;
}
}

In this case, the _myText field is the backing field for the property, and it is manually declared.
When using the more compact C# (or VB) syntax for property declaration a field is still declared,
but the compiler makes up a name for the field on your behalf. Even this property has a backing
field:
public int MyNumber { get; set; }

Even though you don’t explicitly declare the field or know its name, it is there thanks to some
compiler magic.
CSLA 4 allows you to implement properties using a manual backing field, or with what is called a
managed backing field. In the case of a managed backing field, the CSLA .NET base class manages
the property’s value on your behalf. Examine this property implementation carefully:
public static readonly PropertyInfo<string> MyTextProperty =
RegisterProperty<string>(c => c.MyText);
public string MyText
{
get { return GetProperty(MyTextProperty); }
set { SetProperty(MyTextProperty, value); }
}

Notice that no backing field is explicitly defined, and in this case there’s no compiler magic
involved either; there is no real backing field. Instead, the CSLA .NET base class (usually
BusinessBase<T>) is managing the value of the property on your behalf.

The advantage of using manual backing fields is that you gain a slight performance benefit,
because private fields are directly allocated in memory. If you are building Silverlight or WP7
applications, the drawback to using these fields is that you must write code to explicitly serialize
those property values during all serialization and deserialization processing. CSLA 4 supports this
scenario, but you need to be aware that this extra work is required. I’ll discuss the specifics later in
this chapter.
The advantage of using managed backing fields is that your code is simpler, and if you are
building Silverlight or WP7 applications all managed field values are automatically serialized and
deserialized as needed. It is important to note that there is a small performance impact to using
managed backing fields; because the CSLA .NET base class must manage the values in a data
structure somewhat like an optimized dictionary.

Using CSLA 4: Creating Business Objects Page 17


Rev 1.1
My general recommendation is to use managed backing fields, and to only switch to
manual backing fields for specific classes when required by performance or other
specific issues.

In the next section of this chapter I’ll walk through the types of property declaration and
implementation using managed backing fields, and then I’ll show how they are implemented using
manual backing fields.

Properties and Stereotypes


In Chapter 3, I will discuss various business domain object stereotypes, and the CSLA .NET base
classes that support each stereotype. These stereotypes interact with property implementations,
because different base classes provide different behaviors to support each stereotype.
For example, BusinessBase supports the editable object stereotype, and so enables property
implementations that utilize authorization, business rules, data binding and so forth. The
CriteriaBase class, on the other hand, is designed to be a very lightweight container for data
values, and so has no behaviors around authorization, business rules or data binding.
In all cases, the same basic structure applies: register the property metadata, then implement
getter and setter code using GetProperty, ReadProperty, SetProperty, and LoadProperty
depending on which behaviors are required for your scenario.

Types of Property Declaration


CSLA 4 supports several types of property syntax for business classes created by subclassing
BusinessBase or ReadOnlyBase. These are listed in Table 7.

Declaration type Property gets or sets


Read-write property value A primitive or standard .NET type (such as
string) that can can be read or altered
Read-write property value with A value where the property type is different
conversion from the type of the field containing the
property value; the property can be read and
altered, and the property value is automatically
converted to and from the field type
Read-only property value A primitive or standard .NET type (such as
string) that can be read, and has a non-public
setter
Read-only property value with A primitive or standard .NET type (such as
conversion string) that can be read, and has a non-public
setter, and the property value is automatically
converted to and from the field type
Child object reference A reference to a child object (containment
relationship), typically with a public getter and
non-public setter

Using CSLA 4: Creating Business Objects Page 18


Rev 1.1
Child object reference with lazy loading A reference to a child object (containment
relationship), typically with a public getter and
non-public setter, where the child object is only
created or retrieved on-demand
Inter-graph reference A reference to another object in the same object
graph, but not a child, typically with a public
getter and setter
Using reference A reference to another object outside the object
graph, typically with a public getter and no
setter
Properties with manual backing fields Implementing properties using private manual
backing fields, including read-write and read-
only properties

Table 7. Types of property declaration supported by CSLA 4


I’ll walk through each type of property, starting with the most common: a read-write property. I
will discuss the read-write property in a lot of detail, with a little less focus on the other property
types, mostly because once you understand how a read-write property works, the other property
types follow the same pattern, with slight variations.

Read-Write
Perhaps the most common type of property is the read-write property. This is a property with a
public getter and setter designed to allow code using the object to get and set the property value,
subject to all authorization and business rules, and triggering all appropriate data binding and other
behaviors.
public static readonly PropertyInfo<string> MyTextProperty =
RegisterProperty<string>(c => c.MyText);
public string MyText
{
get { return GetProperty(MyTextProperty); }
set { SetProperty(MyTextProperty, value); }
}

Registering the Property


First, the property metadata is defined:
public static readonly PropertyInfo<string> MyTextProperty =
RegisterProperty<string>(c => c.MyText);

Notice that the RegisterProperty method is generic, and so it gets the type of the value being
stored for the property (string in this case). Also notice that a lambda expression is passed as a
parameter to RegisterProperty to provide a strongly-typed reference to the property itself:
c => c.MyText

Behind the scenes, the RegisterProperty method takes this lambda expression and uses
reflection to get access to the PropertyInfo object from System.Reflection corresponding to this
property. It uses that PropertyInfo object to obtain other metadata about the property.

Using CSLA 4: Creating Business Objects Page 19


Rev 1.1
Some alternate overloads of RegisterProperty allow you to pass the text name of the property
as a string value, but I recommend you avoid those overloads because they reduce the
maintainability of your code.
The RegisterProperty method also looks at the property to see if it has a Display attribute
from the System.ComponentModel.DataAnnotations namespace. This attribute can be used to
provide a human readable friendly name for the property, and if that attribute is present then that
friendly name is used as part of the property’s metadata.

Getting the Value


The property getter uses the GetProperty method, which accepts the static metadata field,
MyTextProperty, as a parameter. This metadata field is what tells GetProperty which property
value to retrieve. As a first step, any authorization rule associated with this property is checked, and
the property value is only returned if the user is authorized to see the value.
If the user is not authorized to read the property value, the default value of the property is
returned. No exception is thrown if the user is not authorized to read the value. This is important,
because there are numerous data binding scenarios where a UI developer can not prevent data
binding from reading the value, and so if the getter threw an exception in that case it may crash the
application, or at least cause issues with data binding.
A good UI will have also used the authorization rule support in CSLA 4 to hide or disable the UI
element that would display the value, so the user won’t see even this default value that is returned.
The property itself will return only the default value, not the real value, and a good UI won’t even
show that default value to the user because it will take the authorization rule into account as well.
To support this scenario, every editable business object exposes a public method
CanReadProperty that can be invoked by the UI code. In many cases CSLA 4 has UI helper
components that assist the UI developer in building an authorization-aware user experience, and I’ll
discuss those components in the ebooks dealing with each UI technology.

Setting the Value


The property setter uses the SetProperty method, which accepts the static metadata field, to
identitfy the property value to be set, as well as the value parameter that contains the new value
for the property.
For simple properties, the SetProperty flow is relatively straightforward and usually involves the
following steps:

1. Check authorization rules and throw an exception if user isn’t allowed to change the value

2. Raise the PropertyChanging event

3. Change the property value

4. Mark the business object as having been changed

5. Invoke any business rules associated with the property

Using CSLA 4: Creating Business Objects Page 20


Rev 1.1
6. Invoke any business rules for properties associated with this property (dependent properties)

7. Raise the PropertyChanged event

Add a few more elements, and the process can become much more complex, as illustrated in
Figure 1.

New value
Yes No
different?

Unhook any old


Ignore
event handlers
input
(child object only)

Raise
Mark field as
Yes PropertyChanging
changed?
event

Change value

No
Mark field as
changed
Change value
Raise
PropertyChanged
event

New value is Set parent


Yes
child object? reference

Set edit level

No Hook changed
event

Done

Figure 1. Process followed when setting a property value

Using CSLA 4: Creating Business Objects Page 21


Rev 1.1
You should keep in mind that Figure 1 covers not only setting a primitive or simple property
value, but also shows some elements that occur when setting a child object reference. I’ll discuss
how child, inter-graph and using object references work later in this chapter, at which time I’ll refer
back to this figure again.
I want to call your attention to the fact that a SecurityException is thrown if an attempt is
made to set the property when the current user isn’t authorized to change the property. This is
different from the GetProperty behavior, where an exception isn’t thrown.
The reason for throwing an exeption in the setter, is that a good UI will never allow the user to
attempt to change the property, so there should never be a case where the setter is called if the
user isn’t authorized. If the setter is called when the user isn’t authorized, throwing an exception
makes sense, because it is an indication that the UI developer has introduced a bug into the
application by allowing this to occur.
You should also notice that the SetProperty method is what invokes business rules associated
with this property, and with any other properties marked as being dependent on this property. I’ll
discuss this behavior in more detail later in this ebook in the chapter covering business rules.
Finally, notice that SetProperty also interacts with data binding by raising the PropertyChanged
event. This is the minimum functionality required by all data binding mechanisms, and is one of
several areas of data binding support provided by CSLA .NET.

You should be aware that the PropertyChanged event is handled differently by


Windows Forms, and if you are building a Windows Forms user interface you should
set Csla.ApplicationContext.PropertyChangedMode to Windows, instead of Xaml
(the default). While this isn’t strictly necessary, you may see a performance
improvement because this setting will optimize how the event is raised to work
better with Windows Forms.

At this point, you should have an understanding of the property registration process and how
property getters and setters work with read-write properties. The other types of property
implementation are mostly variations on this same set of concepts.

Read-Write with No Rules


A scenario closely related to the standard read-write property is where you need a read-write
property, but without any authorization or business rule processing.
Sometimes you might want this type of property as a “private field” within a business object;
merely as a place to store a value. While you can use private fields for .NET-only code, when
building business types that need to serialize to Silverlight or WP7 it is often easier to create a
private managed property as I’ll show here.
Sometimes this is a requirement of a business stereotype or CSLA .NET base class. Several base
classes, including CommandBase, CriteriaBase, and CslaIdentity don’t support any sort of
authorization or business rules, and so this syntax is required when implementing properties when
you subclass those base types.

Using CSLA 4: Creating Business Objects Page 22


Rev 1.1
The only difference in code is that the ReadProperty and LoadProperty methods are used
instead of the GetProperty and SetProperty methods:
public static readonly PropertyInfo<string> MyTextProperty =
RegisterProperty<string>(c => c.MyText);
public string MyText
{
get { return ReadProperty(MyTextProperty); }
set { LoadProperty(MyTextProperty, value); }
}

Remember from Table 5 that these two helper methods get and set property values without
invoking any business rules. When implementing read-write properties in classes other than those
inheriting from BusinessBase, this is the syntax you should use.
If you want to create a “private field” you can make the property non-public:
public static readonly PropertyInfo<string> MyTextProperty =
RegisterProperty<string>(c => c.MyText);
private string MyText
{
get { return ReadProperty(MyTextProperty); }
set { LoadProperty(MyTextProperty, value); }
}

Notice that I’ve left the static metadata field public in scope, even though the property itself is
private. You may choose to make the metadata field private in scope, but this will block certain
data access models. In particular, you won’t be able to easily use the ObjectFactory data access
models because the factory object will have no way to interact with the field value. I’ll discuss this
in more detail in the CSLA 4: Data Access ebook.

Read-Write with Value Conversion


Sometimes you may have a property where the type of the property is not the same as the type of
the underlying data field. As long as the two types (the type of the property and the type of the
backing field) are convertible, CSLA .NET makes it very easy for you to create a property of one type,
but maintain the value in a different type.
Perhaps the most common example of this is where you have a string property that is backed
by an enum value.

While this technique is widely used, it is important to realize that it doesn’t lend
itself to localization because there’s no way to change the enum to reflect the user’s
culture or language.

Suppose you have a simple enum like this:


public enum TestEnum
{
Item1,
Item2,
Item3
}

This is the value you want to have in your object, but you want to expose the value to the UI or
other consuming code as its string representation, with automatic parsing of any input values into
the enum value type and having your property getter convert the enum to a string.
Using CSLA 4: Creating Business Objects Page 23
Rev 1.1
In this example, a string property should only allow the values "Item1", "Item2" or "Item3",
because those are the text representations of the underlying numeric enum value.
This can be done by using GetPropertyConvert and SetPropertyConvert in your property
implementation:
public static readonly PropertyInfo<TestEnum> MyStringEnumProperty =
RegisterProperty<TestEnum>(c => c.MyStringEnum);
public string MyStringEnum
{
get { return GetPropertyConvert<TestEnum, string>(MyStringEnumProperty); }
set { SetPropertyConvert<TestEnum, string>(MyStringEnumProperty, value); }
}

Notice that the property type is string, but the RegisterProperty call uses the type TestEnum.
What this means is that the CSLA .NET field manager infrastructure will store a value of type
TestEnum in memory, but the public-facing property is of type string.

The GetPropertyConvert method takes two generic type parameters. The first is the type of the
backing field value (TestEnum) and the second is the type of the property (string). Code setting the
property might look like this:
obj.MyStringEnum = "Item2";

The code could attempt to set the value to text that can’t be parsed as an enum value:
obj.MyStringEnum = "abc";

That will result in a PropertyLoadException from the Csla namespace being thrown by the
SetPropertyConvert method.

Any code reading the property value will get a string result, containing the text name of one of
the valid enum values.
As I mentioned earlier, this value conversion process will work as long as the property type and
the backing field type are convertible following the .NET type conversion rules. There are many
mechanisms by which .NET allows a value of one type to be converted into another type, and CSLA
.NET will attempt to apply every one of those techniques to perform the conversion. If two types
are not convertible, then GetPropertyConvert and SetPropertyConvert will throw type conversion
exceptions at runtime.

Accessing the Underlying Field Value


The final thing that is important to understand when using properties that do type conversion is
how to get at the underlying backing field value. Any use of the property itself will trigger the
conversion, but the code within your business class will almost certainly need access to the
underlying backing field value.
To accomplish this, I recommend implementing another property that exposes the value
directly:
private TestEnum MyEnum
{
get { return GetProperty(MyStringEnumProperty); }
set { SetProperty(MyStringEnumProperty, value); }
}

Using CSLA 4: Creating Business Objects Page 24


Rev 1.1
You can choose to make this property public or non-public as you choose. The important thing to
notice is that you do not need to call RegisterProperty a second time. This property is already
registered, you are exposing it directly without conversion of the value type.

Read-Only
Perhaps the second most common type of property is a read-only property. There are a couple
variations on how you will implement a read-only property, depending on the CSLA .NET base class
from which you inherit to create your business class.

Read-Only with Authorization


The BusinessBase and ReadOnlyBase classes support authorization rules for read-only properties
and so your subclasses will implement read-only properties to use the GetProperty method:
public static readonly PropertyInfo<int> IdProperty = RegisterProperty<int>(c => c.Id);
public int Id
{
get { return GetProperty(IdProperty); }
private set { LoadProperty(IdProperty, value); }
}

In this case, the property getter is the same as with a read-write property, and the GetProperty
method will enforce any authorization rule associated with this property as I discussed earlier.
The property setter is private in scope, and uses the LoadProperty method instead of
SetProperty. The LoadProperty method is used based on the assumption that read-only properties
won’t normally be changed during the lifetime of the object.
If you do intend to change the value of a read-only property during the lifetime of the object,
you will typically change the property setter to call SetProperty instead, so you get normal
business rule and data binding behaviors as the property changes.

Read-Only without Authorization


There are several base classes in the CSLA .NET framework that support read-only properties, but
which don’t support business or authorization rules. These include CommandBase, CriteriaBase, and
CslaIdentity. In this case you’ll need to use the ReadProperty method instead of the GetProperty
method when implementing the property:
public static readonly PropertyInfo<int> IdProperty = RegisterProperty<int>(c => c.Id);
public int Id
{
get { return ReadProperty(IdProperty); }
private set { LoadProperty(IdProperty, value); }
}

The basic structure is the same, but in this case the ReadProperty method is used, so no
authorization rules are checked when the property getter is invoked.

Read-Only with Value Conversion


Creating a read-only property with conversion involves the use of the ReadPropertyConvert and
LoadPropertyConvert methods. By now you are probably familiar with the overall pattern and
should be getting a solid understanding of the basic concepts behind property implementations.

Using CSLA 4: Creating Business Objects Page 25


Rev 1.1
Here’s an example of a read-only property with value conversion, using an enum as the field type
and a string as the property type:
public static readonly PropertyInfo<TestEnum> MyStringEnumProperty =
RegisterProperty<TestEnum>(c => c.MyStringEnum);
public string MyStringEnum
{
get { return ReadPropertyConvert<TestEnum, string>(MyStringEnumProperty); }
private set { LoadPropertyConvert<TestEnum, string>(MyStringEnumProperty, value); }
}

Similarly, you can have a read-only property with value conversion that applies authorization
rules in the getter by using GetPropertyConvert:
public static readonly PropertyInfo<TestEnum> MyStringEnumProperty =
RegisterProperty<TestEnum>(c => c.MyStringEnum);
public string MyStringEnum
{
get { return GetPropertyConvert<TestEnum, string>(MyStringEnumProperty); }
private set { LoadPropertyConvert<TestEnum, string>(MyStringEnumProperty, value); }
}

Once the static metadata field has been declared, you have access to all the getter and setter
helper methods and can mix and match them as necessary to implement your properties.

Child Object Reference


Implementing a property that references a child object is a little different from the simple
properties you’ve seen so far. Specifically, I need to introduce a new overload of RegisterProperty
where you specify a RelationshipTypes value.
The RelationshipTypes enum includes a Child entry, which is used to specify that a property
value represents a reference to a child object. In this section I’ll be using an Addresses property in a
PersonEdit parent class:
public static readonly PropertyInfo<AddressEditList> AddressesProperty =
RegisterProperty<AddressEditList>(c => c.Addresses, RelationshipTypes.Child);
public AddressEditList Addresses
{
get { return GetProperty(AddressesProperty); }
private set { LoadProperty(AddressesProperty, value); }
}

The CSLA .NET framework uses this relationship type information to understand that this is a
child reference, so it can automatically handle a number of scenarios around n-level undo and
object persistence on your behalf.
Notice that the getter uses the GetProperty method, so only authorized users can get access to
the child object, and that the setter is private in scope and uses the LoadProperty method to set
the field value with the child object reference.
With a property implementation like the one shown here, the child object is typically created as
part of the process of creating the parent object. I’ll discuss this in more detail in the Using CSLA 4:
Data Access ebook, but in general your code that creates or retrieves the parent object will include
a line of code to initialize the child property:
Addresses = DataPortal.CreateChild<AddressEditList>();

Using CSLA 4: Creating Business Objects Page 26


Rev 1.1
The specifics of this code can be different depending on which data access model you are using,
but the basic concept is the same: an instance of the child object is created or retrieved, and the
property value is set to reference that child object instance.

Child Object Reference with Lazy Loading


Sometimes you’ll want to lazy load a child object. This is useful in situations where the user usually
doesn’t view or use the child object, but might occasionally need access to the child behaviors or
data.

If the user usually views or uses the child object, it is more efficient to create or
retrieve the child object at the same time you create or retrieve the parent object.

Lazy loading is typically implemented by leaving the child property value as null until the
property getter is invoked. Only if some code calls the property getter do you know that the child
object is required, and so that’s the point at which you create or retrieve the child object. This
process is different depending on whether you are using synchronous or asynchronous data access.
While I will show you how to implement each type of property here, I’ll cover the sync vs async
issues in more detail in the Using CSLA 4: Data Access ebook.
You must specify another relationship type in RegisterProperty to tell CSLA .NET that you are
using lazy loading for the property: RelationshipTypes.LazyLoad. This information is used by CSLA
.NET to properly handle child properties that are lazy loaded. For example, the previous Addresses
property could be changed like this:
public static readonly PropertyInfo<AddressEditList> AddressesProperty =
RegisterProperty<AddressEditList>(c => c.Addresses,
RelationshipTypes.Child | RelationshipTypes.LazyLoad);

Notice that both the Child and LazyLoad values are specified because this is a lazy loaded child
property.

Creating or Retrieving the Child Object


The next thing to consider when lazy loading a child object is that CSLA .NET is designed to support
n-tier deployments. It is quite possible that the parent object is running on a client workstation
when the child property getter is invoked. In that case, it is often necessary to communicate with
the application server to create or retrieve the child object, because client workstations typically
can’t interact with the database server directly.
This means you need to use the data portal to create or retrieve the child object. There are two
ways to do this. One is to directy use the data portal to create the child object as a root object, and
then to coerce the object to be a child, the other is to create a separate “child object creator”
object that is responsible for creating the child object. I will show you this second option, as it is the
most elegant and clear solution.
Using the idea of an Addresses property where I want to lazy load an AddressEditList object,
I’ll create an AddressListCreator class that has a Result property:
[Serializable]
public class AddressListCreator : ReadOnlyBase<AddressListCreator>
{
public static readonly PropertyInfo<AddressEditList> ResultProperty =
Using CSLA 4: Creating Business Objects Page 27
Rev 1.1
RegisterProperty<AddressEditList>(c => c.Result);
public AddressEditList Result
{
get { return ReadProperty(ResultProperty); }
private set { LoadProperty(ResultProperty, value); }
}

public static void GetAddressListCreator(


EventHandler<DataPortalResult<AddressListCreator>> callback)
{
DataPortal.BeginFetch<AddressListCreator>(callback);
}

#if !SILVERLIGHT
public static AddressListCreator GetAddressListCreator()
{
return DataPortal.Fetch<AddressListCreator>();
}

private void DataPortal_Fetch()


{
Result = DataPortal.CreateChild<AddressEditList>();
}
#endif
}

Notice how the example data access code in the AddressListCreator class populates the
Result property with the newly created child object.

Again, the specifics of this code can be different depending on which data access model you are
using, but the basic concept is the same: an instance of the child object is created or retrieved, and
the property value is set to reference that child object instance.
This AddressListCreator is then used to implement the lazy loading of the child object in the
parent class’s property getter. The specific code to do this will be somewhat different for synch vs
async scenarios, so I’ll cover each option.

Synchronous Lazy Loading


If you are going to synchronously load the child object, you’ll build your child property in the parent
class like this:
public static readonly PropertyInfo<AddressEditList> AddressesProperty =
RegisterProperty<AddressEditList>(c => c.Addresses,
RelationshipTypes.Child | RelationshipTypes.LazyLoad);
public AddressEditList Addresses
{
get
{
if (!FieldManager.FieldExists(AddressesProperty))
{
var creator = AddressListCreator.GetAddressListCreator();
Addresses = creator.Result;
}
return GetProperty(AddressesProperty);
}
private set
{
LoadProperty(AddressesProperty, value);
OnPropertyChanged(AddressesProperty);
}
}

Using CSLA 4: Creating Business Objects Page 28


Rev 1.1
The FieldManager.FieldExists method is used to determine whether the child property has
already been loaded. If not, then the data portal is used to retrieve an instance of the
AddressListCreator type. When an AddresssListCreator instance is created on the server, it
creates or retrieves an instance of the AddressEditList child type, which is then available in the
Result property.

The parent object’s Addresses property value is then set to this Result value. Notice that the
setter includes an explicit call to OnPropertyChanged, because LoadProperty doesn’t raise the
PropertyChanged event, but when doing lazy loading it is a good idea to ensure this event is raised
so any UI elements or other code bound to this property value are notified that there is now a child
object available.
Now that the property value has been loaded with a value, the normal GetProperty method is
invoked to return the value to the calling code.

Asynchronous Lazy Loading


For most smart client scenarios you’ll want to use asynchronous lazy loading to avoid locking up the
user interface while the child object is being created. In the case of Silverlight and WP7 you must
use async lazy loading, because those platforms require async interaction with servers.
Async lazy loading is somewhat similar in implementation:
public static readonly PropertyInfo<AddressEditList> AddressesProperty =
RegisterProperty<AddressEditList>(c => c.Addresses,
RelationshipTypes.Child | RelationshipTypes.LazyLoad);
public AddressEditList Addresses
{
get
{
if (!FieldManager.FieldExists(AddressesProperty))
{
LoadProperty(AddressesProperty, null);
AddressListCreator.GetAddressListCreator((o, e) =>
{
if (e.Error != null)
throw e.Error;
else
Addresses = e.Object.Result;
});
}
return GetProperty(AddressesProperty);
}
private set
{
LoadProperty(AddressesProperty, value);
OnPropertyChanged(AddressesProperty);
}
}

The primary difference from the synchronous implementation is that the BeginFetch method is
called on the data portal instead of the Fetch method. This means that the AddressListCreator is
retrieved asynchronously.
Obviously this has a pretty significant impact on the overall workflow. The calling code that
attempted to call this property will get a null result, because the property doesn’t yet exist, but the
attempt to access the property starts the async process of loading the property with a value.

Using CSLA 4: Creating Business Objects Page 29


Rev 1.1
Notice that the property value is set to null before the async load process is started. This
ensures that the temporary null value is available to any code calling the property getter, and also
that the async load process only runs one time.
The BeginFetch method of the data portal requires a callback implementation: code that will be
invoked when the asynchronous operation is complete. In this implementation I’m using a lambda
expression for the callback, so this is the code that runs when the async task completes:
{
if (e.Error != null)
throw e.Error;
else
Addresses = e.Object.Result;
}

It is important to always check the e.Error value to find out if any exceptions occurred during
the async operation. One of the most common challenges people face when doing async
programming is that an exception occurs on a background thread or on the server, and they forget
to check e.Error and so are unaware of what went wrong.

Exceptions that occur on a background thread or on the server during an async


operation will silently disappear unless you explicitly check e.Error. It is important
to always check e.Error in your callback code.

If there was no exception, e.Object contains the result of the BeginFetch call, which means it
contains the AddressListCreator object. That means the code can load the Addresses property
value from its Result property.
When the Addresses property is set, the OnPropertyChanged method is invoked in the setter,
which means the PropertyChanged event is raised for the child property. This is the signal to any
calling code (such as the UI) that there is now a child object available. In most cases, data binding
will automatically respond to the PropertyChanged event and will rebind the UI controls to the
newly available child object.
I will revisit lazy loading of child properties in the Using CSLA 4: Data Access ebook, because your
implementation of the “child creator” object (AddressListCreator in this example) is dependent
on the data access model you choose.
The important thing to understand is that the parent object’s property implementation is
unaffected by the data access model. The implementation I’ve shown here is consistent, and any
differences due to data access choices are abstracted within the child creator class implementation.

Properties with Manual Backing Fields


So far I’ve been showing you how to implement properties using managed backing fields. In these
examples, CSLA .NET has been managing the underlying field value of each property. There are
some cases where you’ll want or need to use private or manual backing fields. In those cases the
code for implementing a property is a little different.
Examples of where you might use manual backing fields include:

 Inter-graph references
Using CSLA 4: Creating Business Objects Page 30
Rev 1.1
 Using relationship references
 Scenarios where you need to apply attributes to fields
 High-performance scenarios where using managed backing fields is a performance
bottleneck

The first three items in the list are inter-related, because implementing an inter-graph reference
or using relationship requires that you apply attributes directly to the backing field for the property.
The last item, performance, should be relatively rare. While there is some performance benefit
to using manual backing fields over managed backing fields, it is typically not a meaningful
difference. My recommendation is to implement using managed backing fields, and fall back to
using manual backing fields only if you encounter an issue where their performance benefit is worth
the extra complexity.
Even when using a manual backing field, you will still register a static metadata field for the
property. It is important to specify the PrivateField relationship type when registering such a
property.
Overloads of the helper methods exist that work with private fields. So the overall structure of
a property remains consistent. For example:
public static readonly PropertyInfo<string> CityProperty =
RegisterProperty<string>(c => c.City, RelationshipTypes.PrivateField);
private string _city = CityProperty.DefaultValue;
public string City
{
get { return GetProperty(CityProperty, _city); }
set { SetProperty(CityProperty, ref _city, value); }
}

Notice how a private backing field is manually declared, and initialized with the DefaultValue
property from the static metadata field. Initializing the field like this helps maintain consistency
with the behavior of managed backing fields.
Next, look at the GetProperty and SetProperty method calls, and notice how the backing field is
passed as a parameter to each method. Most notably, it is passed by ref to SetProperty so that
helper method can efficiently change the field value, while still applying the same authorization,
business rules and other processing that you get with managed backing fields.
In fact, the behavior of this property is identical to its managed implementation, which would
look like this:
public static readonly PropertyInfo<string> CityProperty =
RegisterProperty<string>(c => c.City);
public string City
{
get { return GetProperty(CityProperty); }
set { SetProperty(CityProperty, value); }
}

It is important to realize that only GetProperty and SetProperty have overloads that support
manual backing fields. There’s no need for ReadProperty, LoadProperty or the type conversion
overloads, because your code always has direct access to the field itself. If you need to get or set
the field value without invoking business rules or other standard processing, you can interact

Using CSLA 4: Creating Business Objects Page 31


Rev 1.1
directly with the field. Similarly, if you need to do type conversion between the field and the
property types, you can manually do that in your getter and setter code.

Loosely Typed ReadProperty and LoadProperty Methods


The exception is that there are loosely typed ReadProperty and LoadProperty overloads that can
be used to set any field value, managed or manual:
var val = ReadProperty(CityProperty);
LoadProperty(CityProperty, value);

These overloads exist to enable certain data access layer scenarios and I’ll discuss them in more
detail in the Using CSLA 4: Data Access ebook. You should know that they involve the use of some
late bound technologies to get and set the value and so do have some performance cost. Despite
this performance cost, they can provide a standard, loosely typed way to get and set values, and so
are very valuable when building certain types of decoupled data access layers.

Serialization of Simple Types for Silverlight and WP7


If you implement properties with manual backing fields, and plan to use your types in Silverlight or
WP7, you will need to write some extra code to enable serialization and deserialization of those
field values. In pure .NET code, CSLA .NET will use serializers that are able to directly access all fields
of an object, even private fields. Silverlight doesn’t allow that sort of access for security reasons,
and so those .NET serializers (BinaryFormatter and NetDataContractSerializer) don’t exist in
Silverlight.
To overcome that limitation, CSLA .NET includes its own serializer: MobileFormatter. This
serializer is designed to automatically serialize properties that use managed backing fields.
Properties implemented with manual backing fields are not automatically serialized, and you must
help the MobileFormatter serialize and deserialize the field values.

If you do not add the code to support serialization, your field values will not be
copied between client and server, nor will n-level undo operate against those field
values.

For simple property types (not reference types), this is a matter of overriding two methods in
your class: OnGetState and OnSetState. If your property is a reference type, you’ll need to override
OnGetChildren and OnSetChildren, and you’ll also need to make certain that the object being
referenced implements the IMobileObject interface from Csla.Core.
Table 8 lists the types that are considered “simple types” by MobileFormatter. These types are
directly supported as field values by the serialization process.

Type Description
Value types Types such as int, double, DateTime, etc.
string The string data type
Zero-based enum values A value of type enum can be serialized, as long as
the enum is zero-based (has a value
corresponding to 0)

Using CSLA 4: Creating Business Objects Page 32


Rev 1.1
Table 8. Types directly serialized by MobileFormatter
For the City property example, you need to implement the following code to support
serialization:
protected override void OnGetState(
Csla.Serialization.Mobile.SerializationInfo info, Csla.Core.StateMode mode)
{
info.AddValue("_city", _city);
base.OnGetState(info, mode);
}

protected override void OnSetState(


Csla.Serialization.Mobile.SerializationInfo info, Csla.Core.StateMode mode)
{
_city = info.GetValue<string>("_city");
base.OnSetState(info, mode);
}

Because string is a simple property type, the value can be added to the serialization stream in
OnGetState, and retrieved from the serialization stream in OnSetState. The result is that when
MobileFormatter serializes the object, the _city value is included in the serialized data, and when
it deserializes the byte stream, the _city value is restored from the serialized data.

Serialization of Reference Types for Silverlight and WP7


If your field is an object reference, then the object it references must implement IMobileObject or
MobileFormatter won’t be able to serialize the reference. The easiest way to implement this
interface is to inherit from one of the standard CSLA .NET base classes (such as BusinessBase), or to
subclass one of the more primitive types in Table 9 from Csla.Core.

Base type Description


MobileBindingList A subclass of BindingList from
System.ComponentModel that can be serialized
by MobileFormatter; objects in the list must
be simple types or must implement
IMobileObject (in Silverlight this type is a
subclass of ObservableCollection, because
BindingList doesn’t exist in Silverlight)
MobileDictionary A subclass of Dictionary<K,V> from
System.Collections.Generic that can be
serialized by MobileFormatter; keys and
objects in the dictionary must be simple types or
must implement IMobileObject
MobileList A subclass of List<T> from
System.Collections.Generic that can be
serialized by MobileFormatter; objects in the
list must be simple types or must implement
IMobileObject
MobileObject Implements IMobileObject, enabling relatively
easy construction of types with fields and child
objects that can be serialized by

Using CSLA 4: Creating Business Objects Page 33


Rev 1.1
MobileFormatter
MobileObservableCollection A subclass of ObservableCollection from
System.Collections.ObjectModel that can
be serialized by MobileFormatter; objects in
the list must be simple types or must implement
IMobileObject

Table 9. Serialization base classes in Csla.Core


Additionally, any such type must have the Serializable attribute on the class.
To serialize and deserialize a reference type, the parent object must override the OnGetChildren
and OnSetChildren methods.
Consider a property that references an object that conforms to the requirements listed above
(marked as Serializable and implements IMobileObject):
public static readonly PropertyInfo<PersonEdit> PersonProperty =
RegisterProperty<PersonEdit>(c => c.Person, RelationshipTypes.PrivateField);
private PersonEdit _person = null;
public PersonEdit Person
{
get { return GetProperty(PersonProperty, _person); }
set { SetProperty(PersonProperty, ref _person, value); }
}

The following code is necessary to serialize and deserialize this reference on Silverlight and WP7:
protected override void OnGetChildren(
Csla.Serialization.Mobile.SerializationInfo info,
Csla.Serialization.Mobile.MobileFormatter formatter)
{
base.OnGetChildren(info, formatter);
if (_person != null)
{
var personInfo = formatter.SerializeObject(_person);
info.AddChild("_person", personInfo.ReferenceId);
}
}

protected override void OnSetChildren(


Csla.Serialization.Mobile.SerializationInfo info,
Csla.Serialization.Mobile.MobileFormatter formatter)
{
if (info.Children.ContainsKey("_person"))
{
var personInfo = info.Children["_person"];
_person = (PersonEdit)formatter.GetObject(personInfo.ReferenceId);
}
base.OnSetChildren(info, formatter);
}

The OnGetChildren method serializes the PersonEdit object by calling the SerializeObject
method of the provided formatter object. The resulting serialized data is added to the serialization
stream by calling the AddChild method.
In the OnSetChildren method, the PersonEdit object is restored from the serialization stream
by retrieving the serialized data, and then calling the GetObject method on the supplied formatter
object. The result is cast to the correct type and used to set the _person field value.

Using CSLA 4: Creating Business Objects Page 34


Rev 1.1
As you can see, using manual backing fields with Silverlight and WP7 requires some extra work,
especially for object references. When possible you should use the standard CSLA .NET base types,
or at least the serialization base types in Csla.Core to simplify the process of implementing
serialization and the IMobileObject interface. If you absolutely must manually implement
IMobileObject, I recommend using the classes in Csla.Core as examples for your implementation.

Inter-Graph Reference
Sometimes you’ll have one object in your object graph that references another object, but it isn’t a
child relationship. For example, a PersonEdit object might contain a list of AddressEdit objects,
and those would be child objects. But PersonEdit might also have a PrimaryAddress property that
references one of the addresses in the list. This is an inter-graph reference, but isn’t a child
reference.
The distinction here is subtle but important, and it relates to the way n-level undo works within
CSLA .NET. Calling BeginEdit on a parent object raises the parent’s edit level by one, and also raises
all its child objects’ edit levels by one. This allows you to later call CancelEdit or ApplyEdit on the
parent to undo or commit all changes made to the object graph in memory.
If a child object is considered to be a child twice then when BeginEdit was called on the parent
object, that child object would have its edit level raised twice instead of once. The result would be
an edit level mismatch, because the child would be doubly edited and out of sync with the rest of
the object graph.
To avoid this issue, you need to mark the reference with the NotUndoable attribute. This
attribute goes on the backing field for the property, and so you must implement this property using
a manual backing field. For example, here’s a PrimaryAddress property from the PersonEdit class:
public static readonly PropertyInfo<AddressEdit> PrimaryAddressProperty =
RegisterProperty<AddressEdit>(c => c.PrimaryAddress, RelationshipTypes.PrivateField);
[NotUndoable]
private AddressEdit _primaryAddress = PrimaryAddressProperty.DefaultValue;
public AddressEdit PrimaryAddress
{
get { return GetProperty(PrimaryAddressProperty, _primaryAddress); }
set { SetProperty(PrimaryAddressProperty, ref _primaryAddress, value); }
}

Notice the use of the NotUndoable attribute on the backing field. This tells CSLA .NET that this
object reference should not be included as part of any n-level undo operation.
Remember that you must override the OnGetChildren and OnSetChildren methods for this
property value to correctly serialize to and from the server if this code is used on Silverlight or WP7.

Using Reference
A using relationship is a reference to an object outside the object graph. In other words, you have a
business object that is referencing another object, and that other object is not contained within, or
included as part of, the same set of objects. Another way to think about this, is that this other
object shouldn’t serialize to and from the server along with your business object.
The best way to implement a using relationship is to avoid storing any reference to the other
object at all. Instead, any time you need to interact with this other object you should create an

Using CSLA 4: Creating Business Objects Page 35


Rev 1.1
instance of that object, or get a reference to that object and only keep the reference in a local
variable.
For example, suppose I have an InvoiceEdit object that for some reason needs to change a
person’s name. An InvoiceEdit object doesn’t contain a PersonEdit object, but it might use a
PersonEdit object to implement a SetPersonName method:
public void SetPersonName(int personId, string name)
{
var person = PersonEdit.GetPerson(personId);
person.FirstName = name;
person = person.Save();
}

While the InvoiceEdit object is retrieving and using a PersonEdit object, it doesn’t keep the
reference, and so there are no issues with maintaining object references, n-level undo or
serialization. This is the ideal situation.

Maintaining a Reference
There may be scenarios where you do need to maintain a reference to an object you are using over
a period of time. In that case you’ll need to implement a property with a manual backing field so
that field can be decorated with the NotUndoable and NonSerialized attributes.
It is also the case that this type of property is typically implemented with a form of lazy or on-
demand loading of the object to be used. This is important, because after deserialization the
property value will always be null, so the property getter must handle that case and initialize the
value.
public static readonly PropertyInfo<PersonEdit> PersonProperty =
RegisterProperty<PersonEdit>(c => c.Person);
[NonSerialized]
[NotUndoable]
private PersonEdit _person = PersonProperty.DefaultValue;
public PersonEdit Person
{
get
{
if (_person == null)
_person = PersonEdit.NewPerson();
return GetProperty(PersonProperty, _person);
}
}

Notice the use of the NonSerialized and NotUndoable attributes, which prevent this field from
being serialized by .NET and from being part of n-level undo processing in CSLA .NET.
Also notice that the getter includes lazy loading code to get an instance of the object on-
demand. This way the target object is created when necessary, even after serialization and
deserialization.
In this example I’ve chosen not to implement a setter at all, because the value is only retrieved in
the getter. This is a pretty typical implementation. If necessary you may certainly implement a
setter.
Finally, you should not override OnGetChildren or OnSetChildren for this field value. The whole
idea is to not serialize the value, so you don’t want to add code to serialize it by overriding these
methods.
Using CSLA 4: Creating Business Objects Page 36
Rev 1.1
Non-Generic LoadProperty Method
Several types of property implementation use the LoadProperty method to set a property’s value
without executing business rules. The LoadProperty method shown in the examples in this chapter
is a generic overload of the method that accepts an IPropertyInfo<T> parameter to identity the
affected property.
There is also a non-generic LoadProperty method overload designed for use in certain scenarios.
Specifically, this non-generic overload is designed for use when implementing web or service
interfaces, or data access code, where the types of the input data and property aren’t known until
runtime.
The non-generic overload is substantially slower than the generic overload, because the value
types aren’t known at compile time. You should use the non-generic overload only if there’s no way
to invoke the generic overload.
Normal property implementation code should always have access to the field containing the
property’s metastate, and so should be able to use the generic overload.
At this point, you should understand how to declare and implement properties using managed
and manual backing fields, as well as properties that reference child and non-child objects.

Method Declarations
As with properties, CSLA 4 provides a formal syntax for declaration and implementation of methods
in a business class. This includes a static field containing metadata about the method, and a helper
method that invokes authentication so your method can easily determine whether the current user
should be allowed to invoke the method.
As you might guess, this means there’s a RegisterMethod method that corresponds to
RegisterProperty, and an IMethodInfo interface in Csla.Core that corresponds to the
IPropertyInfo interface. You use RegisterMethod to establish metadata about the method, and to
create a static metadata field you can use to represent that method when adding your
authorization rule.
public static readonly MethodInfo TestMethod = RegisterMethod(typeof(EditableProperties), "Test");
public void Test()
{
CanExecuteMethod(TestMethod, true);
// do some work here
}

The primary difference from a property is that it is up to the author of the method to check the
authorization rule before allowing the method to execute. This means that the first line of code in
your method is typically a call to CanExecuteMethod, which will throw a SecurityException if the
current user isn’t authorized to execute the method.

Metastate
The CSLA .NET framework helps you create business domain objects that maintain their own status
or metastate. These days this type of object is sometimes called a self-tracking object.

Using CSLA 4: Creating Business Objects Page 37


Rev 1.1
Business domain objects created using CSLA .NET automatically track a number of properties and
raise a number of events to provide rich behaviors you can leverage when building and using your
business layer.
Table 10 lists the metastate properties tracked by CSLA .NET objects.

Property Description Stereotypes


IsNew Is there a reasonable expectation Editable root and child
that the object’s primary key value
has a corresponding record in the
database or other data store
IsDeleted Is the object marked for deletion, so Editable root and child
when it is saved it will either not do
an insert, or will do a delete instead
of an update
IsChild Is this object a child of another object Editable root and child
Editable list
IsDirty Has the object, or any of its child Editable root and child
objects, been changed Editable list
IsSelfDirty Has the object been changed Editable root and child
(ignoring the state of any child
objects)
IsValid Is the object, and all its child objects, Editable root and child
valid: meaning there are no broken Editable list
validation rules
IsSelfValid Is the object valid (ignoring the state Editable root and child
of any child objects): meaning there
are no broken validation rules
IsBusy Is the object or any of its properties Editable root and child
or child objects executing any Editable list
asynchronous operations
IsSelfBusy Is the object or any of its properties Editable root and child
(ignoring the state of any child
objects) executing any asynchronous
operations
IsSavable True only if the object and its child Editable root and child
objects are valid, has changes, isn’t Editable list
running any async operations, and
the current user is authorized to
perform the operation

Table 10. Metastate properties of CSLA .NET business objects

Using CSLA 4: Creating Business Objects Page 38


Rev 1.1
Where possible CSLA 4 maintains this metastate on your behalf, so you can use use the various
metastate properties. In some cases you may want or need to directly manipulate the metastate,
and there are methods that allow your code to do so.
Additionally there are some cases where you may want to redefine how the metastate works,
and there are virtual properties or methods that enable those scenarios as well. Obviously you must
fully understand how CSLA .NET uses the metastate before overriding any existing behaviors, or you
can cause unexpected and undesirable results.
Beyond these properties, there are numerous events raised at different points in an object’s
lifecycle. The most important events are listed in Table 11.

Event Description Stereotypes


PropertyChanged A property has changed (if the Editable root and child
property name is null or
string.Empty then all properties
are assumed to have changed)
PropertyChanging A property is about to be changed Editable root and child
ListChanged The list, or an item in the list, has Editable list
changed (applies to BindingList
subclasses only)
CollectionChanged The collection, or an item in the Editable list
collection, has changed (applies to
ObservableCollection subclasses
only)
ChildChanged A child object somewhere deeper in Editable root and child
the object graph has changed (may Editable list
apply to child, grandchild, etc)
Saved The object graph has been saved Editable root
Editable root list
BusyChanged The object’s busy status (IsBusy or Editable root and child
IsSelfBusy) has changed Editable list

Table 11. Events raised by CSLA .NET business objects

Accessing Metastate
The metastate values tracked by business objects are available directly on editable objects, and also
through interfaces.

Public Properties
The metastate properties listed in Table 10 are all public properties of BusinessBase (and
BusinessListBase where appropriate). This means you can access these properties directly on any
editable business object instance.

Using CSLA 4: Creating Business Objects Page 39


Rev 1.1
ITrackStatus Interface
The ITrackStatus interface exposes the most commonly used metastate properties. The reason for
exposing these properties through an interface is to enable polymorphism across different types of
editable object, so you can write code that uses the metastate regardless of the specific object type.
This interface is implemented by BusinessBase, BusinessListBase and
BusinessBindingListBase, making the metastate easily available from any editable object.

INotifyBusy Interface
The INotifyBusy interface enables you to write polymorphic code to determine the busy status of
any business object. Through this interface, you can access the object’s busy status and also handle
its BusyChanged event to be notified when the status has changed.

INotifyChildChanged Interface
The INotifyChildChanged interface defines an event you can use to determine when a child object
in an object graph has been changed. The ChildChanged event is unique, in that it cascades all the
way up the object graph, starting with the immediate parent of the object that changed, but being
raised by every parent object all the way to the root object of the object graph.
You can use this interface to be notified of changes to an object graph regardless of the type of
objects in the graph.

Data Binding
The metastate properties do not directly support data binding, and as they change they do not raise
the PropertyChanged event. This is due to the way Windows Forms data binding works, and due to
the way Visual Studio has implemented its drag-and-drop data binding support.
In WPF, Silverlight and WP7 you will want your UI to bind to many of these metastate properties
to automatically enable and disable various UI elements. In the Using CSLA 4: Silverlight 4 and WPF
ebook I’ll discuss how the ViewModelBase, ViewModel and CslaDataProvider types in the
Csla.Xaml assembly/namespace address this issue.

Basic Status
The basic status properties indicate whether the object is believed to be new or old, and whether it
has been marked for deletion.

IsNew Property
A “new” object is one where there is a reasonable expectation that the object has no corresponding
data in the database or data store. Typically this means that the object’s primary key value doesn’t
correspond to a primary key in the database.
Objects are typically new when:

 They were created by the data portal by calling Create, BeginCreate or CreateChild
 The object has been deleted

Using CSLA 4: Creating Business Objects Page 40


Rev 1.1
In both of these cases, there is a reasonable expectation that the object does not correspond to
data in the database.
You can determine if an object is new by checking the IsNew property on any subclass of
BusinessBase.

IsDeleted Property
Any subclass of BusinessBase will have an IsDeleted property. This property will be true if the
object is marked for deletion.
CSLA .NET supports two models for deleting editable root objects: immediate and deferred. I’ll
discuss these in more detail in the Using CSLA 4: Data Access ebook, but you should know that it is
rare for an editable root object to support deferred deletion. As a result, IsDeleted is almost
always false for root objects.
Conversely, editable child objects are always deleted through deferred deletion. This means that
the object is marked for deletion, and is only deleted when the object graph is saved. After a child
object has been marked for deletion, IsDeleted is true.
Once an object’s IsDeleted property has been set to true, it can’t be directly changed to false.
You must use the undo concept provided by CSLA .NET to revert the object graph to a previous
state in order to “undelete” an object.
The reason for this requirement is that when a child object is marked for deletion the parent
object is usually also affected. For example, removing a child object from a BusinessListBase
collection not only causes the child’s IsDeleted property to be true, but it causes the parent
collection to move the child out of the active collection and into to a DeletedList collection object.
To undelete the child, the object must be moved back into the active collection, and its IsDeleted
property must be set to false.
The undo behavior will automatically ensure that both the parent and child objects are reverted
to an earlier state prior to the deletion of the child object.

IsSavable Property
The IsSavable property exists on all editable objects, and it indicates whether the object is in a
state where it can be saved (inserted, updated or deleted in the data store). The IsSavable
property is a combination of several other properties and exists as a convenience.
An object is considered savable if:

 The object and all child objects are valid


 The object or any child object has been changed
 The object and all child objects are not running any async operations
 The user is authorized to perform the save operation

The primary purpose of this property is to allow a UI developer to easily determine whether the
object can be saved so appropriate buttons, links and menu items can be enabled and disabled as
appropriate.
Using CSLA 4: Creating Business Objects Page 41
Rev 1.1
MarkDeleted and Delete Methods
The MarkDeleted method is a protected method of BusinessBase, and you can call this method to
mark an object for deletion. This method sets the IsDeleted property to true. You should not
normally need to directly call MarkDeleted, because it is invoked automatically in almost all cases.
There is a Delete method as well, and it is public in scope. This method calls MarkDeleted, but it
only operates on editable root objects. By default, calling Delete on an editable child object will
cause an exception to be thrown. The Delete method exists to help support the use of deferred
deletion of editable root objects.
The reason Delete isn’t available on child objects, is that child objects should be deleted through
their parent. Typically child objects are contained in collections (a subclass of BusinessListBase),
and they are “deleted” by calling one of the remove methods on the collection. When an object is
“removed” from a BusinessListBase or BusinessBindingListBase collection, it is marked for
deletion and is moved to a DeletedList, so when the object graph is saved the underlying data can
be deleted from the database. This is all automatic and you don’t need to do anything for this to
occur.
The Delete method is virtual, so if you need to customize the rules around marking editable
root objects for deletion, you can override the existing behavior.
Once an object is marked for deletion there is no “undelete” concept. If you need to “undelete”
an object, you chould call CancelEdit on that object, or its parent object, thus causing the
IsDeleted property value to be restored to its previous state.

MarkNew Method
The MarkNew method is a protected method of BusinessBase, and you can call this method to mark
an object as being new. You should not normally need to directly call MarkNew, because it is invoked
automatically in most cases.
This method sets the IsNew property to true, the IsDeleted property to false and calls the
MarkDirty method (which I’ll discuss later).

The MarkNew method is virtual so you can override its behavior. The most common reason for
overriding MarkNew is to change whether a new object is considered to have been changed or not.
By default, when MarkNew is called it invokes MarkDirty. This means all new objects are also
considered to have changed. Sometimes people prefer that new objects not be considered to have
changed, and so they override MarkNew as follows:
protected override void MarkNew()
{
base.MarkNew();
MarkClean();
}

The result of this change is that new objects are considered to be new (IsNew is true), but they
are considered to have no changes (IsSelfDirty is false).

MarkOld Method
The MarkOld method is a protected method of BusinessBase, and you can call this method to mark
an object as being old (not new). An “old” object is an object where there’s a reasonable
Using CSLA 4: Creating Business Objects Page 42
Rev 1.1
expectation that the object’s data corresponds to data in the database or data store. In most cases
this means that the primary key value of the object directly corresponds to a row with that primary
key in the database.
The MarkOld method sets IsNew to false and calls MarkClean (which I’ll discuss later). Normally
this method is called automatically by CSLA .NET when an object is inserted or updated into the
database, at which point there is clearly a reasonable expectation that the data in the object
corresponds directly to a set of data in the database.
This method is virtual, so you can override its behavior.

Change Tracking
Editable business objects keep track of whether their state has been changed. An object is
considered “dirty” if any of its properties have been changed.
For performance and memory optimization reasons, CSLA .NET uses a fairly simplistic
mechanism to track whether an object has been changed. If a property value is changed, the object
is considered to have been changed. Even if the property is changed back to its orginal value, the
object is still considered to have been changed.
If you need finer grained information over whether the object has been changed, it is possible
(with some work) to override the way CSLA .NET tracks that whether objects and properties have
been changed. The technique involved is covered by Jason Bock in this blog post:
http://www.jasonbock.net/JB/Default.aspx?blog=entry.9cc70d85bef34e2b9a683ba82615f8a3

Change tracking is managed by a couple properties and methods.

IsDirty Property
The IsDirty property is true if the object, or any of its child objects, have been changed. The data
portal uses this property to avoid trying to save objects that haven’t been changed, and you can use
this property to detect whether the object graph has changes as well.
This property is virtual, so you can override its behavior to implement more complex change
tracking mechanisms, though in most cases you should look at overriding the IsSelfDirty property
instead.

IsSelfDirty Property
The IsSelfDirty property returns true if the object’s state has been changed. This includes
changes to the object’s properties, as well as some metastate. For example, calling MarkDeleted will
cause IsSelfDirty to return true, because that represents a change to the object’s state.
When any property in the object is changed, a Boolean flag is set to true. By default, the
IsSelfDirty property returns the value of that flag. This is a very low-impact implementation of
change tracking that provides high performance and little memory consumption.
This property is virtual, so you can override its behavior to implement more complex change
tracking mechanisms. For example, if you replace the way field values are managed as described in
Jason Bock’s blog post, you can override IsSelfDirty to determine whether the object has been
changed by finding out whether any specific properties of the object have been changed.
Using CSLA 4: Creating Business Objects Page 43
Rev 1.1
MarkClean Method
The MarkClean method is a protected method on BusinessBase. Normally you don’t have to call
this method directly, as it is invoked automatically by CSLA .NET. This method sets the internal
Boolean change tracking flag to false, indicating that the object has no changes.
The MarkClean method also tells the field manager to mark every property as being unchanged.
By default this has no impact, but if you’ve replaced the default field management types with more
complex types you can use this information to update your internal field storage values.
Finally, the method calls OnUnknownPropertyChanged, which raises the PropertyChanged event
with a property name of string.Empty. This tells data binding to refresh the bindings on all the
properties of the object, ensuring that the UI is up to date based on any changes that were
committed to the object’s state or metastate.

PropertyHasChanged Method
The PropertyHasChanged method is a protected method on BusinessBase that is invoked when
individual property values of a business object are changed. You don’t normally need to invoke this
method, as it is invoked automatically by CSLA .NET when property values change.
This method calls the MarkDirty method (discussed later), and raises the PropertyChanged
event as appropriate based on the value of Csla.ApplicationContext.PropertyChangedMode . The
default mode is Xaml, which means the PropertyChanged event is raised in a way that is compatible
with all UI technologies, including WPF, Silverlight, WP7 and Windows Forms. Please note that it is
not optimized for Windows Forms and the default will cause a lot of extra UI refresh activity. So if
you are building a Windows Forms application you should change the mode to Windows to optimize
for that environment.

Be aware that setting the PropertyChangedMode to Windows will cause WPF data
binding to work incorrectly.

If you do set the PropertyChangedMode, remember it is a global setting that affects the way the
PropertyChanged event is raised by all editable objects in your application.

MarkDirty Method
The MarkDirty method is a protected method on BusinessBase. You don’t normally have to call
this method directly, as it is invoked automatically by CSLA .NET (typically from the
PropertyHasChanged method). This method sets the internal Boolean change tracking flag to true,
indicating that the object has been changed.
By default this method not only effectively sets IsSelfDirty to true, it also raises the
PropertyChanged event with a property name of string.Empty. This tells data binding to refresh
the bindings on all the properties of the object, ensuring that the UI is up to date based on any
changes that were committed to the object’s state or metastate.
It is also possible to call a MarkDirty overload that accepts a Boolean value indicating that the
method should suppress the raising of the PropertyChanged event. In this case the method marks
the object as having been changed.

Using CSLA 4: Creating Business Objects Page 44


Rev 1.1
Object Validity
Editable business objects keep track of whether they are valid. Being “valid” means that the object
has no broken validation rules for the object or any of its properties.
I’ll discuss validation and business rules in Chapter 4, but for now you should understand that
when validation rules are executed, the result is a list of broken rules that is maintained for each
business object. If there are no broken rules (with Error severity) in this list, then the object is valid.

IsValid Property
The IsValid property returns true if the current object and all its child objects are valid. If the
current object or any of its child objects have any broken validation rules then IsValid will return
false.
This property is virtual so you can customize its behavior if required. This would be an
advanced scenario where you’ve decided to create your own validation mechanism or something of
that sort.

IsSelfValid Property
The IsSelfValid property returns true if the current object has no broken validation rules. The
state of child objects is ignored by this property. You can use this property to determine the validity
of a specific object rather than an object and its children.
This property is also virtual so you can customize its behavior if required. This would be an
advanced scenario where you’ve decided to create your own validation mechanism or something of
that sort.

Busy Tracking
A “busy” object is an object that is executing an asynchronous operation. Examples of asynchronous
operations include:

 Asynchronous business rules


 Asynchronous validation rules
 Asynchronous data portal calls (such as calling BeginSave)

Asynchronous business and validation rules are managed at the property level. This means a
specific property is busy, as well as the business object. Another way to say this, is that a business
object is busy if it is busy, or if any of its properties are busy.
A busy object can’t be saved. This is because the results of the asynchronous operation won’t be
known until that operation completes, so the object is in an indeterminate state while any async
operation is executing.

IsBusy Property
The IsBusy property returns true if the object or any child object is executing an async operation.
This property allows you to easily determine of an object graph has any async operations running,
so you can do things like disable UI elements or show a busy animation as appropriate.
Using CSLA 4: Creating Business Objects Page 45
Rev 1.1
This property is virtual so you can override its behavior. You shouldn’t normally need to
override the IsBusy property, because even if you customize the way async operations work in your
objects, you’d normally override the IsSelfBusy property.

IsSelfBusy Property
The IsSelfBusy property returns true if the object or any of its properties are executing async
operations. The state of child objects is ignored by this property. Again, you can use this property to
enable busy animations or disable parts of the UI as appropriate.
This property is virtual so you can override its behavior. You may choose to do this if your
object has alternate ways of becoming busy. If you implement new ways to execute async
operations beyond the ones I’ve listed in this chapter, you would override the IsSelfBusy property
so you can include your async operations as part of the object’s busy status.

IsPropertyBusy Method
The IsPropertyBusy method can be used to determine if a specific property is busy. A property is
busy if one or more async business or validation rules attached to the property are currently
executing.

BusyChanged Event
The IsBusy property can change for several reasons:

 A child object becomes busy or idle


 A property a child object becomes busy or idle
 A property of the object becomes busy or idle
 The object itself becomes busy or idle

The BusyChanged event is raised when the busy status of the object or a property on the object
changes, and includes a BusyChangedEventArgs parameter that contains information about the
change.
The BusyChangedEventArgs type includes a Busy property and a PropertyName property.
When a property of the object becomes busy or idle, the BusyChanged event is raised to indicate
the change for that specific property. In that case the PropertyName property contains the name of
the affected property.
When the object or a child of the object becomes busy or idle, the BusyChanged event is raised
and the PropertyName property of the event args parameter is string.Empty. An empty
PropertyName value indicates that the state of the object itself has changed, not only the state of a
specific property.

MarkBusy Method
If you want to directly mark the object as busy you can call the MarkBusy method. This is a
protected method available in BusinessBase and ReadOnlyBase. Normally MarkBusy is invoked
automatically, and you don’t need to call this method.
Using CSLA 4: Creating Business Objects Page 46
Rev 1.1
It is important to understand that calling MarkBusy has no effect on whether there are async
operations running for specific properties, this method only impacts the object’s busy status.
An object is only allowed to become busy if it is idle. Calling MarkBusy when the object is already
busy will result in an exception.
Calling MarkBusy marks the object as busy and raises the BusyChanged event.

MarkIdle Method
If you want to directly mark the object as idle you can call the MarkIdle method. This method marks
the object as idle and raises the BusyChanged event. It is important to understand that calling
MarkIdle has no effect on whether there are async operations running for specific properties, this
method only impacts the object’s busy status.
You should not normally need to call the MarkIdle method, because it is called automatically as
appropriate. You should only call MarkIdle if it was your code that explicitly called MarkBusy to
make the object appear busy.
At this point, you should have an understanding of the basic concepts surrounding business
domain objects created using CSLA .NET. These concepts include support for various object
relationships, property and method declarations and metastate management.
Next, I’ll discuss the basic solution structures typically used when creating applications using
CSLA .NET. Then I’ll cover the different object stereotypes supported by the CSLA .NET base classes.
Finally, I’ll cover business rules.

Using CSLA 4: Creating Business Objects Page 47


Rev 1.1
Chapter 2:
Solution Structure
When using CSLA .NET to create a project, you can use many different project structures: ways of
organizing your classes into projects and projects into solutions. In this chapter, I’ll discuss the way I
structure solutions and projects to make the best of use CSLA 4.

Project Types and Assembly References


It is important to reference the correct assemblies and correct build of each assembly based on
your project types. If you attempt to reference the incorrect assembly build, Visual Studio may stop
you with an error. Alternatly, it may allow the reference, but you’ll encounter runtime errors when
attempting to execute your code.
Table 12 shows the most common project types and the CSLA .NET assemblies typically
referenced by those projects.

Project type Referenced assemblies Visual Studio Profile


.NET Class Library Csla.dll .NET Client Profile
Silverlight Class Library Csla.dll Silverlight 4
Windows Phone Class Library Csla.dll Windows Phone 7
WPF Application Csla.dll .NET Client Profile
Csla.Xaml.dll
Windows Forms Application Csla.dll .NET Client Profile
Csla.Windows.dll
Silverlight Application Csla.dll Silverlight 4
Silverlight Business Application Csla.Xaml.dll
Silverlight Navigation Application
Windows Phone Application Csla.dll Windows Phone 7
Windows Phone Databound Application Csla.Xaml.dll
Windows Phone Panorama Application
Windows Phone Pivot Application
ASP.NET Web Application Csla.dll .NET Full Profile
Csla.Web.dll
ASP.NET MVC Web Application Csla.dll .NET Full Profile
Csla.Web.dll
Csla.Web.Mvc.dll

Table 12. Common project types and related CSLA assembly references
Taking some care to reference the correct assemblies and assembly builds when setting up each
project can save you a lot of headaches when you start trying to build and run your solution code.

Using CSLA 4: Creating Business Objects Page 48


Rev 1.1
Combining Projects to Create Solutions
Most applications will be created by building a Visual Studio solution that is composed of several
projects. In many cases these projects correspond directly to the logical architectural layers
discussed in the Using CSLA 4: CSLA .NET Overview ebook.
Table 13 shows a typical set of projects for a simple WPF Application.

Project name Project type Description References


MyApp WPF Application Contains the Interface and MyApp.Library.dll
Inteface Control layers that
comprise the user interface
MyApp.Library .NET Class Library Contains the business classes MyApp.Dal.dll
that make up the business
layer of the application
MyApp.Dal .NET Class Library Contains the data access code Various options as
necessary to map data from discussed in the Using
your data store into and out of CSLA 4: Data Access
the business objects ebook

Table 13. Typical projects in a WPF Application


The references listed here in Table 13 are in addition to the CSLA .NET references listed earlier in
Table 12.

While it is possible to combine all the code into a single project, I recommend using
this type of multi-project solution to help reinforce the concept of the logical layers
within your application’s architecture. Even most highly skilled and disciplined
developers have a very difficult time maintaining clear layer boundaries without
using this technique.

In an n-tier physical deployment, you’ll have at least one server between the client and
database. For example, Table 14 shows a 4-tier Silverlight solution.

Project name Project type Description References


MyApp Silverlight Application Contains the Interface and MyApp.Library.dll
Inteface Control layers that (build for Silverlight)
comprise the user interface
MyApp.Library.Net .NET Class Library Contains the business MyApp.Dal.dll
classes that make up the
business layer of the
application
MyApp.Library.Sl Silverlight Class Library Contains the business <none>
classes that make up the
business layer of the
application

Using CSLA 4: Creating Business Objects Page 49


Rev 1.1
MyAppWeb ASP.NET Web Application The web site that hosts the MyApp.Library.dll
Silverlight application, and (build for .NET)
exposes the Silverlight data
portal so the Silverlight app
can call back to the server
MyAppAppServer ASP.NET Web Application Hosts the .NET data portal, MyApp.Library.dll
or AppFabric host and therefore the server- (build for .NET)
side application server MyApp.Dal.dll
behaviors
MyApp.Dal .NET Class Library Contains the data access Various options as
code necessary to map data discussed in the
from your data store into Using CSLA 4: Data
and out of the business Access ebook
objects

Table 14. Typical proejcts in a 4-tier Silverlight Application


It is important to remember that this is probably the most complex scenario supported by CSLA
4, and even most Silverlight applications won’t use a 4-tier deployment.
Even in this more complex solution you should be able to pick out the key parts of the logical
layered architecture from the Using CSLA 4: CSLA .NET Overview:

 Client application (interface and interface control)


 Business layer (in this case build for both Silverlight and .NET)
 Data access layer
 Data portal hosts (necessary for routing messages between client and server)

This is the consistent theme you should look for in any CSLA .NET solution. In general terms,
there should always be a presentation project, a business layer project and a data access project.
Other projects may exist to provide specialized functions such as hosting the data portal, or
providing more flexible data access layers (as discussed in the Using CSLA 4: Data Access ebook).
But the overall pattern should remain consistent.

Reusing Business Assemblies Across Platforms


One important feature of CSLA 4 is that it allows you to create business classes that can be used to
build Windows, Web, Silverlight and Windows Phone applications; all built against the same
business layer and business classes. To make this possible, you must create your own business layer
assemblies (Class Library projects) that contain the same code but which are built for each target
platform (.NET, Silverlight and WP7).
In the example from Table 14 you can see a 4-tier Silverlight application that has a business layer
running on the client, and on the server. The important thing to understand is that we want the
client-side Silverlight and server-side .NET code to use the same business layer; literally to use the
same classes! To make this possible, your solution will need a .NET Class Library to run on the
server, and a Silverlight Class Library to run on the client. Both of these projects need to contain the
exact same business classes, but need to be built for the .NET and Silverlight platforms respectively.
Using CSLA 4: Creating Business Objects Page 50
Rev 1.1
The same concepts and techniques apply to sharing business types with WP7 class libraries.
Visual Studio supports this concept through the idea of linked files. It is possible to create a Class
Library project (the .NET Class Library for example) that contains all your business classes, and to
then link all the code files from that project into another project (such the Silverlight Class Library).
This doesn’t duplicate the files on disk, it shares the exact same code files between the two
projects.

Controlling the Assembly and Namespace Names


CSLA .NET assumes your business type names will be the same regardless of platform. This includes
not only the class name, but also the namespace and assembly names. This means you’ll need to
make sure the .NET and Silverlight projects share the same assembly and namespace names. Figure
2 shows how the Assembly name and Default namespace values have been changed in a
.NET project.

Figure 2. Setting the assembly and namespace names in a .NET project


Notice that the project name is Library.Net, but the assembly and namespace names have
been changed to just Library. Assuming you’ll be linking class files into a corresponding Silverlight
class library, you’d do the same thing (as shown in Figure 3) to the Silverlight project.

Figure 3. Setting the assembly and namespace names in a Silverlight project

Using CSLA 4: Creating Business Objects Page 51


Rev 1.1
Again, notice that the project name is Library.Sl, but the assembly and namespace values have
been changed to be the same as in the .NET project. As you can guess, Figure 4 shows the same
thing for a WP7 project.

Figure 4. Setting the assembly and namespace names in a Windows Phone project
By setting the assembly and default namespace values to be the same in all the projects, you are
ensuring that when the solution is built that you’ll end up with compiled Library.dll files, built for
.NET, Silverlight, and WP7 respectively. And you help ensure that all the classes in both assemblies
share the same namespace.
The whole idea here is that the exact same class code gets compiled for .NET, Silverlight, and
WP7. The only difference is the platform for which the code is compiled, not the code itself.

Linking Files
Once the projects have been set up and their assembly and namespace names changed to be
consistent you can start adding code files to one of the projects. I recommend putting all the code
files into one of the projects and linking the files into the other projects to keep things as simple as
possible.
As an example, Figure 5 shows the .NET project containing code files.

Figure 5. Class library containing code files


These same physical files can be included as part of other projects using this concept of linking
that is built into Visual Studio. To use this feature, right-click on the project where you want to add
the file (such as the Library.Sl project) and choose to add an existing item as shown in Figure 6.

Using CSLA 4: Creating Business Objects Page 52


Rev 1.1
Figure 6. Add an existing item
In the resulting add file dialog, navigate to the folder where the files exist (such as Library.Net)
and select the files to be linked. Then open the Add button menu and choose Add As Link as
shown in Figure 7.

Figure 7. Adding files as a link


The result is that the files are linked into the project as shown in Figure 8.

Using CSLA 4: Creating Business Objects Page 53


Rev 1.1
Figure 8. Project containing linked files
Notice the extra arrow glyph in the lower-left part of each file icon. That indicates that this is a
linked file.
The files are not copied, they only exist on disk one time, in the original project. But they are
included in this other project, and when this project is built these code files are compiled as though
they were directly in this project’s folder on disk.
The value of this is that you only have to maintain the code one time, a change to any business
class immediately affects all projects into which that file is linked. So you are able to share code files
across multiple platforms with very little effort or additional cost.
Remember that in this example Library.Net is a .NET Class Library project referencing Csla.dll
built for the .NET Client Profile, and that Library.Sl is a Silverlight Class Library project referencing
Csla.dll built for Silverlight 4. A corresponding Library.Wp project would be a Windows Phone
Class Library project referencing Csla.dll built for WP7.
So even though all three projects might contain the exact same code files (directly or linked),
they’ll each build the code for a different target platform: .NET, Silverlight, and WP7.

Using CSLA 4: Creating Business Objects Page 54


Rev 1.1
Chapter 3:
Object Stereotypes
I will now walk through each object stereotype, explaining its purpose and illustrating the basic
implementation of a business class following that stereotype. You can find example template code
for each stereotype in the \Support\Templates folder in the CSLA .NET download.

Editable Objects
Editable objects can be created, retrieved, updated, and deleted from the database. These objects
typically contain public read-write properties or child objects, and business rules to support
business, validation, and authorization behaviors for these properties and objects.

Editable Root and Child


Editable root and child objects are objects that support most of the key features of CSLA .NET,
including:

 Contains data that is persisted in a database


 Manages all metastate (new, deleted, valid, busy, dirty)
 Public read-write properties
 Business type is protected with authorization rules
 Properties are protected with authorization rules
 Changing a property triggers business rules (including validation)
 Changing a property triggers data binding behaviors

A parent object’s IsChild property is false, while a child will return true. This property affects
how the object is persisted by the data portal, and is an important distinction I’ll discuss further in
the Using CSLA 4: Data Access ebook.
For the purposes of this ebook, you can consider that editable root and child objects share the
same basic class structure.
[Serializable]
public class EditableRoot : BusinessBase<EditableRoot>
{
public static readonly PropertyInfo<string> NameProperty = RegisterProperty<string>(p => p.Name);
public string Name
{
get { return GetProperty(NameProperty); }
set { SetProperty(NameProperty, value); }
}
protected override void AddBusinessRules()
{
// TODO: add validation rules
base.AddBusinessRules();

//BusinessRules.AddRule(new Rule(NameProperty));
}

Using CSLA 4: Creating Business Objects Page 55


Rev 1.1
public static void AddObjectAuthorizationRules()
{
// TODO: add authorization rules
//BusinessRules.AddRule(...);
}

#if !SILVERLIGHT
public static EditableRoot NewEditableRoot()
{
return DataPortal.Create<EditableRoot>();
}

public static EditableRoot GetEditableRoot(int id)


{
return DataPortal.Fetch<EditableRoot>(id);
}

public static void DeleteEditableRoot(int id)


{
DataPortal.Delete<EditableRoot>(id);
}
#endif

public static void NewEditableRoot(EventHandler<DataPortalResult<EditableRoot>> callback)


{
DataPortal.BeginCreate<EditableRoot>(callback);
}

public static void GetEditableRoot(int id, EventHandler<DataPortalResult<EditableRoot>> callback)


{
DataPortal.BeginFetch<EditableRoot>(id, callback);
}

public static void DeleteEditableRoot(int id, EventHandler<DataPortalResult<EditableRoot>> callback)


{
DataPortal.BeginDelete<EditableRoot>(id, callback);
}
}

Because this is the first stereotype I’m covering, I’ll walk through this code in some detail.
First, notice that the class is marked with the Serializable attribute:
[Serializable]

All business types must be serializable.


Next, look at the class declaration and notice that this is a subclass of BusinessBase<T>, one of
the primary base classes provided by CSLA .NET. The BusinessBase class supports the editable
object stereotypes:
public class EditableRoot : BusinessBase<EditableRoot>

The T type parameter must always be the type of the business class you are creating. This is
because the BusinessBase class needs to have access to this type value for implementation of
strongly-typed property declarations, object cloning and object persistence.
Your class will define its own properties. The one shown here is just an example:
public static readonly PropertyInfo<string> NameProperty = RegisterProperty<string>(p => p.Name);
public string Name
{
get { return GetProperty(NameProperty); }
set { SetProperty(NameProperty, value); }
}

Using CSLA 4: Creating Business Objects Page 56


Rev 1.1
You can use any of the property implementation techniques I discussed earlier in this ebook to
define public or non-public read-write or read-only properties as required by your specific
business requirements. This includes properties that reference child objects.
These properties can be decorated with attributes from
System.ComponentModel.DataAnnotations, including the Display attribute to provide a friendly
name for the property, as well as validation attributes.

This is true even in WP7, because CSLA 4 includes an implementation of the


DataAnnotations attributes for use in WP7 applications, even though there is no
native implementation provided by WP7.

Next notice the override of the AddBusinessRules method. I’ll discuss this method in more
detail in Chapter 4. For now, you should understand that this is the method you need to override to
attach custom business, validation and authorization rules to the properties of your business class.
protected override void AddBusinessRules()
{
// TODO: add validation rules
base.AddBusinessRules();

//BusinessRules.AddRule(new Rule(NameProperty));
}

If you override this method, it is important to call the base implementation because that is
where the DataAnnotations validation attributes are integrated into the CSLA 4 business rules
subsystem.
The next bit of code is an implementation of the AddObjectAuthorizationRules method:
public static void AddObjectAuthorizationRules()
{
// TODO: add authorization rules
//BusinessRules.AddRule(...);
}

This is a static method where you can write code to register authorization rules with your
business class at the type level. I’ll discuss per-type authorization rules in Chapter 4. For now you
should understand that these rules allow you to control which users are allowed to create, retrieve,
update and delete instances of this business type.
For editable child objects this is all the code that is relevant. The remaining code implements the
public factory methods and is found in root objects only. Child types don’t have public factory
methods.
These factory methods call the data portal, which I’ll cover in detail in the Using CSLA 4: Data
Access ebook. You can think of each data portal call as a potential call to an application server,
where the business object will be persisted by your application’s data access layer.
The first set of factory methods are wrapped in a compiler directive that prevents them from
being compiled for Silverlight (or WP7). This is required because these are synchronous methods,
and Silverlight doesn’t support synchronous calls to an application server.
#if !SILVERLIGHT
public static EditableRoot NewEditableRoot()

Using CSLA 4: Creating Business Objects Page 57


Rev 1.1
{
return DataPortal.Create<EditableRoot>();
}

public static EditableRoot GetEditableRoot(int id)


{
return DataPortal.Fetch<EditableRoot>(id);
}

public static void DeleteEditableRoot(int id)


{
DataPortal.Delete<EditableRoot>(id);
}
#endif
}

These factory methods are pretty straightforward. They are static methods that perform
create, retrieve or delete operations for this business type. They rely on the data portal to do all the
work. The factory methods are an abstraction to make it easy for UI code to interact with your
business type. For example, if someone wants to retrieve a specific EditableRoot object, code like
this will do the job:
var obj = EditableRoot.GetEditableRoot(123);

This level of abstraction is very important, because the calling code doesn’t know how the object
was created or loaded with data.
The remaining factory methods are asynchronous, and so can be used on .NET, Silverlight or
WP7.
public static void NewEditableRoot(EventHandler<DataPortalResult<EditableRoot>> callback)
{
DataPortal.BeginCreate<EditableRoot>(callback);
}

public static void GetEditableRoot(int id, EventHandler<DataPortalResult<EditableRoot>> callback)


{
DataPortal.BeginFetch<EditableRoot>(id, callback);
}

public static void DeleteEditableRoot(int id, EventHandler<DataPortalResult<EditableRoot>> callback)


{
DataPortal.BeginDelete<EditableRoot>(id, callback);
}

These factory methods do the same thing: create, retrieve or delete the business class. But they
are asynchronous, and so return no value directly. Instead, any values they return become available
when the asynchronous operation completes, at which time the callback parameter is invoked.
This callback parameter is the address of a method you supply, so it is your method that is invoked
when the operation is complete.
Typical calling code would look like this:
EditableRoot.GetEditableRoot(123, (o, e) =>
{
if (e.Error != null)
throw e.Error;
else
_editableRoot = e.Object;
});

Using CSLA 4: Creating Business Objects Page 58


Rev 1.1
Editable business objects are designed to support public read-write properties with attached
business, validation and authorization rules. They are also designed to support persistence through
the data portal, including create, retrieve, update and delete operations.

Editable Root and Child List


Another type of editable object is an editable collection. This stereotype represents a collection that
supports some key concepts:

 Contains data that is persisted in a database


 Manages some metastate (valid, busy, dirty)
 Business type is protected with authorization rules
 Changing a child object triggers data binding behaviors

An editable list is, by definition, a parent object because the whole idea of a collection is to
contain other objects. The difference between an editable root and child list, is that an editable root
list can be directly persisted through the data portal, while a child list is persisted as part of its
parent.
Changes made to child objects contained in an editable list are made in memory, and are only
persisted to the database when the object graph is persisted through the data portal. The user can
change many child objects, and they’ll be saved to the database as a batch, not one at a time.
[Serializable]
public class EditableRootList :
BusinessListBase<EditableRootList, EditableChild>
{
public static void AddObjectAuthorizationRules()
{
// TODO: add authorization rules
//AuthorizationRules.AllowGet(typeof(EditableRootList), "Role");
}

#if !SILVERLIGHT
public static EditableRootList NewEditableRootList()
{
return DataPortal.Create<EditableRootList>();
}

public static EditableRootList GetEditableRootList(int id)


{
return DataPortal.Fetch<EditableRootList>(id);
}
#endif

public static void NewEditableRootList(EventHandler<DataPortalResult<EditableRootList>> callback)


{
DataPortal.BeginCreate<EditableRootList>(callback);
}

public static void GetEditableRootList(int id,


EventHandler<DataPortalResult<EditableRootList>> callback)
{
DataPortal.BeginFetch<EditableRootList>(id, callback);
}
}

Using CSLA 4: Creating Business Objects Page 59


Rev 1.1
This type is serializable, and it inherits from a CSLA .NET base class: BusinessListBase<T,C>. The
BusinessListBase<T,C> class supports the editable list stereotype by providing support for data
binding, persistence and the parent-child relationships necessary for containment.
Collections do not support direct declaration of properties, so you can’t implement properties in
this class. If properties are required in addition to the list of child objects, you should create an
editable parent object that contains the collection, along with those other properties and their
rules.
Because there are no properties in a collection, the only rules that make sense are the per-type
rules you define by implementing the AddObjectAuthorizationRules method. I’ll discuss
authorization rules in Chapter 4. This method allows you to specify the rules controlling which users
can create, get, save, or delete the collection.
The rest of the code in the class applies to root objects only. Child objects do not have public
factory methods.
The factory methods shown here include synchronous methods wrapped in a compiler directive
so they don’t build for Silverlight or WP7. Again, Silverlight requires asynchronous communication
with application servers, and you should assume any call to the data portal will be calling an
application server.
The last two methods are asynchronous factory methods and so work in .NET, Silverlight, and
WP7.

Adding New Items


Adding new items to a collection can be done in many ways. It is important to remember that an
editable list can only contain editable child objects.

Calling Code Adds Item


One way to add items to a collection is to create the new item (new editable child object) and to
then use the collection’s Add method to add the item to the collection. This is not terribly abstract,
because it requires that the calling code understand how to create a new editable child object. That
is typically done using a Unit of Work object (a stereotype I’ll discuss later in this chapter).
For the following code examples, assume you have an EditableChildCreator object that
understands how to properly create and initialize a new child object. To support this, it would have
a static method named CreateChild that invokes the data portal to create the new child object.
In a synchronous environment the calling code would look like this:
var child = EditableChildCreator.CreateChild();
_list.Add(child);

In an async environment the calling code would look like this:


EditableChildCreator.CreateChild((o, e) =>
{
if (e.Error != null)
throw e.Error;
else
_list.Add(e.Object);
});

Using CSLA 4: Creating Business Objects Page 60


Rev 1.1
The lack of abstraction in this approach is far from ideal, because it pushes too much knowledge
into the calling code. It would be better to hide these details.

Collection Adds Item


Another way to add items to a collection is to implement an AddChild method in the editable list
class itself. Then the calling code would look like this:
_list.AddChild();

The AddChild method itself would still use a Unit of Work object to create the child object, but it
can encapsulate that effort, and can also hide the details of synchronous vs asynchronous
implementations. A synchronous AddChild method would look like this:
public void AddChild()
{
Add(EditableChildCreator.CreateChild());
}

While an asynchronous AddChild method would look like this:


public void AddChild()
{
EditableChildCreator.CreateChild((o, e) =>
{
if (e.Error != null)
throw e.Error;
else
Add(e.Object);
});
}

The calling code can rely on the collection’s CollectionChanged event to know when the async
operation is complete and the new object has been added to the collection.
The advantage of the AddChild method technique is that you encapsulate the details of creating
and adding the child object within the collection class itself. Also, your AddChild method can accept
parameters that might be required to initialize the new child object.

Implementing AddNew
The final technique you can use is the standard AddNew method on editable list objects. This is very
similar to the idea of implementing your own AddChild method, except that you can’t pass
parameter values to the AddNew method.
The benefit of using the AddNew method is that this technique integrates with data binding and
many datagrid controls (in smart client UI technologies) so when the user moves to the bottom row
of a datagrid control a new object is automatically created and added to the collection (and thus the
datagrid).
Although the implementiation of the AddNew is different between .NET and Silverlight, you do
need to set the AllowNew property to true in your collection’s constructor in both platforms:
AllowNew = true;

Setting this property to true tells the runtime that you have implemented the behaviors
necessary for AddNew to work.

Using CSLA 4: Creating Business Objects Page 61


Rev 1.1
The AllowNew property is true by default, and CSLA 4 includes a default synchronous
implementation of the AddNew behavior for both .NET and Silverlight. The AddNew behavior will work
by default.
I will walk through how you implement AddNew. Keep in mind that if you need to customize its
behavior or initialize new child objects with specific data, you’ll need to provide your own
implementation.
In .NET code you implement AddNew by overriding the AddNewCore method from the collection
base class. In your collection class you write code like this:
protected override EditableChild AddNewCore()
{
var child = EditableChildCreator.CreateChild();
Add(child);
return child;
}

Again, I’m using a Unit of Work object to create and initialize a new child object. That child
object is then added to the collection, and is returned as a result of the method.
The code is a little different in Silverlight and WP7, where the implementation is asynchronous.
protected override void AddNewCore()
{
EditableChildCreator.CreateChild((o, e) =>
{
if (e.Error != null)
{
throw e.Error;
}
else
{
Add(e.Object);
OnAddedNew(e.Object);
}
});
}

Because the operation is async, AddNewCore is a void method. Once the new child is created, this
method must call the OnAddedNew method to indicate that the new child has been added to the
collection.

Creating the Child Directly


If you don’t need to initialize your child object with any data as it is created, you can avoid the use
of a Unit of Work object and any communication with any application server. The code I’ve been
using so far relies on a Unit of Work object to abstract the use of the data portal, so any child object
is created by communicating with any application server so the new object can be initialized with
data as necessary.
If you can create child objects with hard-coded default values, you don’t need to go through a
Unit of Work object, and instead you can directly call the CreateChild method on the data portal.
While I’ll get into more detail in the Using CSLA 4: Data Access ebook, I’ll quickly show you the
relevant code here.
For example, the .NET implementation of AddNewCore could look like this:

Using CSLA 4: Creating Business Objects Page 62


Rev 1.1
protected override EditableChild AddNewCore()
{
var child = DataPortal.CreateChild<EditableChild>();
Add(child);
return child;
}

This will cause the data portal to directly create an instance of the child object without any
attempt at talking to an application server.
Similarly, you can do the same thing on Silverlight:
protected override void AddNewCore()
{
var child = DataPortal.CreateChild<EditableChild>();
Add(child);
OnAddedNew(child);
}

The data portal’s CreateChild method is synchronous, so this converts the Silverlight
implementation into what is effectively a synchronous operation. Notice, that OnAddedNew is still
invoked, because that closes the loop to tell the collection and runtime that the add operation is
complete.
The default .NET and Silverlight implementations of AddNew use the data portal’s CreateChild
method that I’ve shown here.
The editable list stereotype enables batch updates of changes to a list of child objects, along with
authorization rules at the type level.

Dynamic Root List and Dynamic Root


CSLA .NET supports two stereotypes for editable collections, the editable list stereotype I discussed
earlier, and a dynamic root list stereotype. The dynamic root list stereotype is quite different,
because in this case, the collection contains root objects that are persisted individually instead of in
a batch. This also requires a slight variation on the editable root stereotype for the objects
contained in a dynamic root list.
The basic concept is that a smart client UI will retrieve a dynamic root list, which is a collection of
dynamic root objects (basically editable root objects). This list will then be data bound to a datagrid
control for in-place editing.

This stereotype is designed specifically to support smart client UI scenarios with a


datagrid control. To use a dynamic root list without a fully functional datagrid
control will require that you simulate all the details of data binding that a datagrid
would normally implement.

As the user edits and leaves each row in the datagrid control, they are effectively concluding the
edit of a root object in the list, so the dynamic root list collection automatically saves the changes to
that object. This occurs automatically and immediately as the user leaves the row in the datagrid
control.

Using CSLA 4: Creating Business Objects Page 63


Rev 1.1
Similarly, if the user adds a new item to the datagrid control, edits the values and leaves the row,
the corresponding root object in the list is saved (inserted) into the database. If the user presses the
ESC key, the new item is removed from the datagrid and collection without being saved.
If the user deletes a row in the datagrid control, the corresponding root object in the collection is
automatically and immediately deleted.
These save and delete operations are managed automatically by the dynamic root list collection
in coordination with the data binding behaviors expected from datagrid controls. You should expect
this to work with most datagrid controls in Silverlight, WPF, and Windows Forms. All persistence
operations are handled by the data portal, and I’ll discuss them in more detail in the Using CSLA 4:
Data Access ebook.

Dynamic Root
A normal editable root object has public factory methods allowing the UI to directly retrieve
instances of the business type. A dynamic root is an editable root designed to be contained within a
dynamic root list, and so responsibility for retrieving each object belongs to the collection.
In most cases this means that a dynamic root object is a normal editable root object without a
public factory method for retrieving (getting) an instance of the type. This also impacts the
implementation of the data access code for fetching the object, because that code will now be
invoked by the “parent” collection instead of directly by the data portal. I’ll get into more details in
the Using CSLA 4: Data Access ebook.
Otherwise, a dynamic root is like an editable root. It will have the same properties, business
rules, factory method for creating the object and so forth.

Dynamic Root List


A dynamic root list is created by subclassing the DynamicListBase<T> base class. This base class
contains the functionality necessary to respond to the data binding interaction with a datagrid
control to automatically create, save and delete the dynamic root objects contained in the
collection.
[Serializable]
public class DynamicRootList : DynamicListBase<DynamicRoot>
{
public static void AddObjectAuthorizationRules()
{
// TODO: add authorization rules
// AuthorizationRules.AllowGet(typeof(DynamicRootList), "Role");
// AuthorizationRules.AllowEdit(typeof(DynamicRootList), "Role");
}

public DynamicRootList()
{
AllowNew = true;
}

#if SILVERLIGHT
protected override void AddNewCore()
{
DynamicRoot.NewDynamicRoot((o, e) =>
{
if (e.Error != null)
{

Using CSLA 4: Creating Business Objects Page 64


Rev 1.1
throw e.Error;
}
else
{
Add(e.Object);
OnAddedNew(e.Object);
}
});
}
#else
protected override DynamicRoot AddNewCore()
{
DynamicRoot item = DynamicRoot.NewDynamicRoot();
Add(item);
return item;
}
#endif

#if !SILVERLIGHT
public static DynamicRootList NewDynamicRootList()
{
return DataPortal.Create<DynamicRootList>();
}

public static DynamicRootList GetDynamicRootList(int id)


{
return DataPortal.Fetch<DynamicRootList>(id);
}
#endif

public static void NewDynamicRootList(EventHandler<DataPortalResult<DynamicRootList>> callback)


{
DataPortal.BeginCreate<DynamicRootList>(callback);
}

public static void GetDynamicRootList(


int id, EventHandler<DataPortalResult<DynamicRootList>> callback)
{
DataPortal.BeginFetch<DynamicRootList>(id, callback);
}
}

As with the other editable types I’ve discussed, this one implements the
AddObjectAuthorizationRules method where you can associate authorization rules to specify the
users that are allowed to create, get, and save this collection.
This class has a constructor that sets AllowNew to true, because the code overrides AddNewCore
to implement the AddNew behavior. While this is optional, you will usually implement the AddNew
behavior so the user can automatically add new items to the datagrid by moving to the last row in
the display.
The concept of overriding AddNewCore is the same as I discussed earlier for the editable list
stereotype. The implementation is different for .NET and Silverlight because the Silverlight
implementation must be asynchronous.
And as with the other root object stereotypes, the dynamic root list implements public factory
methods to allow creation or retrieval of the collection. The synchronous factory methods are
wrapped in a compiler directive so they only build for .NET, while the asynchronous factory
methods are available to .NET, Silverlight, and WP7 code.

Using CSLA 4: Creating Business Objects Page 65


Rev 1.1
The dynamic root list stereotype is very useful for the specific scenario of supporting in-place
editing in a smart client datagrid control, where changes should be automatically committed as the
user leaves each row in the datagrid.

Read-Only Objects
Read-only object stereotypes support the idea that there are many objects that contain read-only
data. These include objects with read-only properties, and collections that don’t allow adding or
removing of items. Read-only objects are generally “lighter weight” than editable objects, because
they don’t need to support concepts like validation rules or change notification for data binding.
Read-only objects don’t track the IsChild metastate value, or most other metastate values.
Because a read-only object only supports read-only properties or child objects, there’s no need to
track whether the object is new, marked for deletion, is valid, or has been changed. None of these
concepts make sense for a read-only object.

Read-Only Root and Child


The read-only root and child stereotypes are essentially identical. The only difference is that a read-
only root will have public factory methods and the child will not.
[Serializable]
public class ReadOnlyRoot : ReadOnlyBase<ReadOnlyRoot>
{
public static readonly PropertyInfo<string> NameProperty = RegisterProperty<string>(p => p.Name);
public string Name
{
get { return GetProperty(NameProperty); }
private set { LoadProperty(NameProperty, value); }
}

protected override void AddBusinessRules()


{
// TODO: add authorization rules
//BusinessRules.AddRule(...);
}

public static void AddObjectAuthorizationRules()


{
// TODO: add authorization rules
// BusinessRules.AddRule(...);
}

#if !SILVERLIGHT
public static ReadOnlyRoot GetReadOnlyRoot(int id)
{
return DataPortal.Fetch<ReadOnlyRoot>(id);
}
#endif

public static void GetReadOnlyRoot(int id, EventHandler<DataPortalResult<ReadOnlyRoot>> callback)


{
DataPortal.BeginCreate<ReadOnlyRoot>(id, callback);
}
}

The base class that supports the read-only object stereotype is ReadOnlyBase<T>. Notice that
this type is serializable and that it inherits from the appropriate base class.

Using CSLA 4: Creating Business Objects Page 66


Rev 1.1
You will implement your own read-only properites based on your business requirements. The
property shown here is one possible example.
public static readonly PropertyInfo<string> NameProperty = RegisterProperty<string>(p => p.Name);
public string Name
{
get { return GetProperty(NameProperty); }
private set { LoadProperty(NameProperty, value); }
}

You can use any of the read-only property implementations I discussed earlier in the chapter. It
is important to understand that the SetProperty and SetPropertyConvert helper methods do not
exist in ReadOnlyBase, because those only make sense for read-write properties.
The GetProperty method exists, because it applies authorization rules as the user attempts to
read the property.
The AddBusinessRules and AddObjectAuthorizationRules methods are similar to those you’d
find in an editable object, except that the only rules enforced in a read-only object are authorization
rules dealing with reading properties and getting an instance of the business type. There is no
concept of business rules, validation rules, or authorization rules covering writing to a property or
saving the object.
It makes no sense to create a “new” read-only object, because that would create an object that
has no data in its read-only properties. It does make sense to retrieve a read-only object, so that
you can see the factory methods (synchronous and asynchronous) which use the data portal to
fetch an instance of the read-only type:
#if !SILVERLIGHT
public static ReadOnlyRoot GetReadOnlyRoot(int id)
{
return DataPortal.Fetch<ReadOnlyRoot>(id);
}
#endif

public static void GetReadOnlyRoot(int id, EventHandler<DataPortalResult<ReadOnlyRoot>> callback)


{
DataPortal.BeginCreate<ReadOnlyRoot>(id, callback);
}

Only a read-only root will have these factory methods. A read-only child will be retrieved as part
of its parent.
The read-only object stereotype is very valuable, because most applications have a lot of
information that needs to be retrieved for display. This stereotype supports that requirement, with
authorization rules and data portal integration.

Read-Only Root and Child List


One of the most common scenarios in an application is the “search screen” where the user is shown
a read-only list of search results, they pick a result and are shown a detail or edit screen. That
scenario is supported by the read-only list stereotype. A read-only list is a collection that isn’t
changed after it is created (no items are added or removed) and it contains read-only objects.
The only difference between a read-only root and child list is that a read-only root list has
public factory methods and a child does not. Here’s an example of a read-only list:

Using CSLA 4: Creating Business Objects Page 67


Rev 1.1
[Serializable]
public class ReadOnlyList : ReadOnlyListBase<ReadOnlyList, ReadOnlyChild>
{
public static void AddObjectAuthorizationRules()
{
// TODO: add authorization rules
// AuthorizationRules.AllowGet(typeof(ReadOnlyList), "Role"); }

#if !SILVERLIGHT
public static ReadOnlyList GetReadOnlyList(string filter)
{
return DataPortal.Fetch<ReadOnlyList>(filter);
}
#endif

public static void GetReadOnlyList(string filter,


EventHandler<DataPortalResult<ReadOnlyList>> callback)
{
DataPortal.BeginFetch<ReadOnlyList>(filter, callback);
}
}

The base class that supports the read-only list stereotype is ReadOnlyListBase<T,C>. The only
type of business rules available in a read-only list are per-type authorization rules that are set up by
implementing the AddObjectAuthorizationRules method. As you might expect, the only
meaningful authorization rule deals with the retrieval of the list object.
The remaining code applies to root objects only, and illustrates the basic factory method
structure you’ve seen in previous stereotypes. Again you see the synchronous .NET-only factory and
the asynchronous factory that applies to all platforms.

Name-Value List
In many older applications one of the most common requirements for a read-only list was to
retrieve a simple name-value pair for use in populating a listbox or combobox control in the UI. This
requirement was so common that I defined the NameValueListBase<K,V> base class to support a
name-value list stereotype.
The name-value list stereotype is an example of a read-only list, but with a pre-built read-only
child object type that only contains a key and a value.
This stereotype is sometimes still useful, but I find that most XAML-based applications require
richer information than a name-value pair for populating their listbox and combobox controls. The
fact that modern UI technologies allow the display of more than a single string value means that
the name-value list stereotype has become less useful over time.
You should feel free to use the NameValueListBase base class if it fits into your application’s
requirements. If you need something more than name-value pairs then you should create a read-
only list with richer read-only child objects.
The most interesting part of the following code is probably the implementation of a simple
client-side cache using a static field. This is entirely optional, but is pretty common for name-value
lists because they often contain data that doesn’t change while the application is running:
[Serializable]
public class NameValueList : NameValueListBase<int, string>
{
private static NameValueList _list;

Using CSLA 4: Creating Business Objects Page 68


Rev 1.1
public static void InvalidateCache()
{
_list = null;
}

#if !SILVERLIGHT
public static NameValueList GetNameValueList()
{
if (_list == null)
_list = DataPortal.Fetch<NameValueList>();
return _list;
}
#endif

public static void GetNameValueList(int id, EventHandler<DataPortalResult<NameValueList>> callback)


{
if (_list == null)
{
DataPortal.BeginFetch<NameValueList>(id, (o, e) =>
{
_list = e.Object;
callback(o, e);
});
}
else
{
callback(null, new DataPortalResult<NameValueList>(_list, null, null));
}
}
}

The class declaration uses the NameValueListBase base class, providing it with the types of the
key and value for the child objects in the list:
public class NameValueList : NameValueListBase<int, string>

In this example the key is of type int and the value is of type string.
The next bit of code implements a simple static field as a cache for the list:
private static NameValueList _list;

public static void InvalidateCache()


{
_list = null;
}

There’s also a method to clear the cache, which can be useful if the application does need to
force the cache to be reloaded with data from the server.
The factory methods are very similar to those you’ve seen, except that they check the static
cache field and return that value if it exists. The data portal is only invoked if there is no pre-existing
cached value.
You can use this same static field cache technique with read-only object and read-only list
objects as well.
The read-only stereotypes are widely used in most applications, because it is extremely common
to display read-only data to a user. In contrast, if your object requires a read-write property, or your
collection must support adding or removing of items, then you should use the editable object
stereotypes.

Using CSLA 4: Creating Business Objects Page 69


Rev 1.1
Execution Objects
Editable and read-only stereotypes have one thing in common: they typically have properties that
are displayed to the user. But not all objects are so focused on data and properties. Nearly every
application needs objects that just do something. These are objects that represent the execution of
an action or a command or a verb or a task.
For example, your application may allow users to create and edit sales orders. But at some point
the user probably chooses a menu option that ships an order, or ships all orders for a certain date.
It is possible that the process of shipping orders is non-interactive. It is a server-side task that runs
through the database updating data and printing shipping documents.
As another example, your Silverlight UI for editing a sales order might need to retrieve the
SalesOrderEdit object, along with several read-only list objects containing values necessary to
populate listbox and combobox controls in the UI. Because all server access in Silverlight is
asynchronous, you need some way to make a single async call to the server to get all those objects
at the same time so your UI will have all the data needed for data binding to work properly.
Theses are examples of execution objects following the two primary stereotypes:

 Command
 Unit of Work

I’ll discuss each stereotype.

Command
The command object stereotype supports a specific sequence of code execution as listed in Table
15.

Step Description
Create object The command object is created by the calling code, typically on
the client workstation.
Initialize object The command object is initialized by the calling code, either
through its constructor or by explicitly setting properties on the
object.
Client execution The command object can run any code that needs to run on the
client before interacting with the server.
Server execution The command object is executed by the data portal, which means
any server-side code is executed after the data portal has moved
the object to the application server.
Client execution The command object comes back from the server through the
data portal, and it can run any code that needs to run on the
client after the server interaction.
Calling code reacts The calling code can interact with the command object once its
execution is complete, often reading property values as results

Using CSLA 4: Creating Business Objects Page 70


Rev 1.1
from the object.

Table 15. Execution sequence of a command object


The base class that supports the command stereotype is CommandBase<T>. Here is an example of
a command class:
[Serializable]
public class CommandObject : CommandBase<CommandObject>
{
#if !SILVERLIGHT
public static bool Execute()
{
CommandObject cmd = new CommandObject();
cmd.BeforeServer();
cmd = DataPortal.Execute<CommandObject>(cmd);
cmd.AfterServer();
return cmd.Result;
}
#endif

public static void BeginExecute(EventHandler<DataPortalResult<CommandObject>> callback)


{
CommandObject cmd = new CommandObject();
cmd.BeforeServer();
DataPortal.BeginExecute<CommandObject>(cmd, (o, e) =>
{
if (e.Error != null)
throw e.Error;
e.Object.AfterServer();
callback(o, e);
});
}

public static PropertyInfo<bool> ResultProperty = RegisterProperty<bool>(c => c.Result);


private bool Result
{
get { return ReadProperty(ResultProperty); }
private set { LoadProperty(ResultProperty, value); }
}

private void BeforeServer()


{
// TODO: implement code to run on client
// before server is called
}

private void AfterServer()


{
// TODO: implement code to run on client
// after server is called
}

protected override void DataPortal_Execute()


{
// TODO: implement code to run on server
// and set result value(s)
Result = true;
}
}

The code starts out with static factory methods that make it easy to invoke the command
synchronously and asynchronously. These factory methods follow the sequence of steps from Table
15, calling methods that are stubbed out for illustration purposes.

Using CSLA 4: Creating Business Objects Page 71


Rev 1.1
The DataPortal_Execute method contains the code that runs on the server. In the Using CSLA 4:
Data Access ebook I’ll describe how this is one of several possible implementations of the server-
side code.
Notice how the asynchronous factory method invokes the AfterServer method in the
completion callback from the data portal’s BeginExecute method. This ensures that the server-side
processing is complete and that the command object has moved back to the client before the
client-side post-processing code is executed.
Also notice the implementation of the Result property:
public static PropertyInfo<bool> ResultProperty = RegisterProperty<bool>(c => c.Result);
private bool Result
{
get { return ReadProperty(ResultProperty); }
private set { LoadProperty(ResultProperty, value); }
}

The only helper methods provided by CommandBase are ReadProperty and LoadProperty.
Command objects have no inherent business rule concept, nor do they support data binding, so the
other helper methods have no meaning.
You can implement any properties that are required by your business requirements. Property
values automatically flow from the client to the server and back to the client through the data
portal as the object moves to and from the application server. This ensures that both client-side and
server-side code have access to the same set of properties.

Unit of Work
The unit of work (UOW) stereotype has always been important, but its use has become more
widespread with the increasing popularity of asynchronous server access techniques.
This is because it is very common for a UI to require several objects be present in memory on the
client before a page, form, or window can be fully rendered or data bound. If you asynchronously
request each of these objects you can’t predict the order in which they’ll be returned to the client,
and writing code to hold off rendering the UI until all the objects are available isn’t easy.
A simpler solution is to make a single request to the server for all the objects required by the UI.
This makes retrieval of several different objects into a single unit of work.
Another somewhat less common scenario, is where more than one object needs to be saved at
the same time, as part of the same logical operation. Perhaps the application allows the user to
enter information about a customer and sales order on the same screen. When the user clicks the
Save button both the CustomerEdit and SalesOrderEdit objects must be saved at the same time. If
either fails, both must fail.
Again, a simple solution to this requirement is to make a single call to the server that combines
the save operations of both objects into a single unit of work.

Data Retrieval
Data retrieval can be described as combining what would have been several object fetch requests
into a single request. The individual objects being requested might be of almost any stereotype

Using CSLA 4: Creating Business Objects Page 72


Rev 1.1
(editable, read-only, name-value list, etc.), but the UOW object itself is a read-only object that is
responsible for fetching all these other objects and returning them to the calling code.
The data retrieval UOW stereotype is a specialized read-only object. For example, here’s a data
retrieval UOW that retrieves two other objects:

[Serializable]
public class CustomerEditRetriever : ReadOnlyBase<CustomerEditRetriever>
{
public static PropertyInfo<CustomerEdit> CustomerEditProperty =
RegisterProperty<CustomerEdit>(c => c.CustomerEdit);
public CustomerEdit CustomerEdit
{
get { return GetProperty(CustomerEditProperty); }
private set { LoadProperty(CustomerEditProperty, value); }
}

public static PropertyInfo<SalesRegionList> SalesRegionListProperty =


RegisterProperty<SalesRegionList>(c => c.SalesRegionList);
public SalesRegionList SalesRegionList
{
get { return GetProperty(SalesRegionListProperty); }
private set { LoadProperty(SalesRegionListProperty, value); }
}

#if !SILVERLIGHT
public static CustomerEditRetriever GetCustomerEditRetriever(int customerId)
{
return DataPortal.Fetch<CustomerEditRetriever>(customerId);
}
#endif

public static void GetCustomerEditRetriever(


int customerId, EventHandler<DataPortalResult<CustomerEditRetriever>> callback)
{
DataPortal.BeginFetch<CustomerEditRetriever>(customerId, callback);
}
}

This UOW class defines two read-only properties; one for each of the objects it will be retrieving.
It implements synchronous and asynchronous factory methods to call the data portal to do the
retrieval. When this object is returned by the data portal, those two properties will contain
references to the objects that were requested.
Although I’ll go into more detail about the data access aspects of this process in the Using CSLA
4: Data Access ebook, here’s one example of how the server-side code might be implemented. This
DataPortal_Fetch method would be included in the CustomerEditRetriever class:
#if !SILVERLIGHT
private void DataPortal_Fetch(int customerId)
{
CustomerEdit = CustomerEdit.GetCustomer(customerId);
SalesRegionList = SalesRegionList.GetList();
}
#endif

I am assuming that the CustomerEdit and SalesRegionList classes are normal root editable and
read-only list objects, and so they have factory methods. The “data access” code in the UOW class
needs to use those factory methods to retrieve the two objects so they can be returned to the
calling code.
Using CSLA 4: Creating Business Objects Page 73
Rev 1.1
This technique is something you should consider any time you need to retrieve multiple objects,
and where the calling code needs to have access to all those objects before it can proceed to use
them.

Data Update
The data update UOW stereotype is slightly different, because any save operation is a “round trip”.
The object starts on the client, and the save operation moves it to the application server so the
object’s state can be saved into the database by the data access layer. Then the object is returned
to the client, because you must assume the object was changed during the save operation.
For example, insert operations typically create new primary key or id values for the object.
Update operations typically create new timestamp values for the object. Delete operations convert
the object from being an existing (old) object into being a new object.
The CommandBase base class is designed to move from client to server and back to the client,
carrying any property values with the object. So it is the perfect base class for building a data
update UOW:
[Serializable]
public class DataUpdateUow : CommandBase<DataUpdateUow>
{
public static PropertyInfo<CustomerEdit> CustomerEditProperty =
RegisterProperty<CustomerEdit>(c => c.CustomerEdit);
public CustomerEdit CustomerEdit
{
get { return ReadProperty(CustomerEditProperty); }
private set { LoadProperty(CustomerEditProperty, value); }
}

public static PropertyInfo<SalesOrderEdit> SalesOrderEditProperty =


RegisterProperty<SalesOrderEdit>(c => c.SalesOrderEdit);
public SalesOrderEdit SalesOrderEdit
{
get { return ReadProperty(SalesOrderEditProperty); }
private set { LoadProperty(SalesOrderEditProperty, value); }
}

#if !SILVERLIGHT
public static DataUpdateUow Update(CustomerEdit customer, SalesOrderEdit order)
{
var cmd = new DataUpdateUow { CustomerEdit = customer, SalesOrderEdit = order };
cmd = DataPortal.Execute<DataUpdateUow>(cmd);
return cmd;
}
#endif

public static void Update(CustomerEdit customer, SalesOrderEdit order,


EventHandler<DataPortalResult<DataUpdateUow>> callback)
{
var cmd = new DataUpdateUow { CustomerEdit = customer, SalesOrderEdit = order };
DataPortal.BeginExecute<DataUpdateUow>(cmd, callback);
}
}

First, you should notice the CustomerEdit and SalesOrderEdit properties. These properties
contain the business objects that are to be updated. Those objects will be serialized from the client
to the server along with the DataUpdateUow object, and they’ll come back from the server through
the data portal as well.
One possible implementation of the server-side code you might write in DataUpdateUow is this:
Using CSLA 4: Creating Business Objects Page 74
Rev 1.1
#if !SILVERLIGHT
[Transactional(TransactionalTypes.TransactionScope)]
private void DataPortal_Execute()
{
CustomerEdit = CustomerEdit.Save();
SalesOrderEdit = SalesOrderEdit.Save();
}
#endif

Both business objects are carried to the application server by the UOW object, which then saves
them within a single transactional context. The resulting business objects are then returned to the
client, so the calling code can make use of any new database-generated id values, timestamp
values, or other new values.
Notice how the factory methods in the UOW class return the UOW object as a result, which is
how the calling code gains access to the resulting properties or results.
The unit of work pattern is a powerful one, and can be used for retrieving or updating data as
I’ve shown here, or for any other scenario where you need do perform more than one operation as
a logical unit of work.

Criteria Objects
When you create a factory method to fetch a root object the factory method typically calls the
Fetch or BeginFetch method of the data portal. This method takes zero or one parameter, which is
the criteria used on the server to find the right information to create and populate the root object
being requested. The same is true for the data portal’s Create, BeginCreate, Delete, and
BeginDelete methods.
That single parameter value is the criteria value used to identify the root object. Criteria values
can be any serializable type. If you are building a pure .NET application this means any value that
can be serialized with the BinaryFormatter or NDCS. If your code will run on Silverlight or WP7 this
means any value that can be serialized with the MobileFormatter.
Generally this means any primitive value type (such as int or double), and some special
reference types like string. It also means any class you’ve created that is serializable.

Simple Criteria
Simple criteria values include:

 Primitive .NET types such as int, double, char, etc.


 Serializable value types such as DateTime and DateTimeOffset
 Special types such as string or Guid
 Serializable reference types (classes you create)

Most business objects use simple primary keys of type int or Guid, which means most of your
data portal calls can pass the simple id or key value as the criteria value.

Using CSLA 4: Creating Business Objects Page 75


Rev 1.1
Complex Criteria
Sometimes multiple values are required to identify a root object. Examples include cases where the
database tables use compound keys, or where the user can provide several search criteria values
that are used to populate a results collection.
In this case you’ll need to create a serializable class with properties for each of the values that
make up the criteria. There are two primary base classes used to create complex criteria types:
CriteriaBase and BusinessBase.

Using CriteriaBase
The CriteriaBase base class is designed to make it easy to create complex criteria types that are
serializable in .NET, Silverlight and WP7. This base class only supports the ReadProperty and
LoadProperty helpers for property implementation, and has no support for business rules,
authorization or data binding.
Here’s an example of a criteria class containing two values:
[Serializable]
public class CustomerCriteria : CriteriaBase<CustomerCriteria>
{
public static PropertyInfo<int> RegionIdProperty = RegisterProperty<int>(c => c.RegionId);
public int RegionId
{
get { return ReadProperty(RegionIdProperty); }
private set { LoadProperty(RegionIdProperty, value); }
}

public static PropertyInfo<int> CustomerIdProperty = RegisterProperty<int>(c => c.CustomerId);


public int CustomerId
{
get { return ReadProperty(CustomerIdProperty); }
private set { LoadProperty(CustomerIdProperty, value); }
}

public CustomerCriteria(int regionId, int customerId)


{
RegionId = regionId;
CustomerId = customerId;
}
}

You would use these criteria in a factory method. For example, the following might be a factory
method for a CustomerEdit editable root:
public static CustomerEdit GetCustomerEdit(int regionId, int customerId)
{
var criteria = new CustomerCriteria(regionId, customerId);
return DataPortal.Fetch<CustomerEdit>(criteria);
}

Notice how the criteria class is used within the factory, so the code calling the factory doesn’t
have to worry about those details. The calling code provides strongly typed parameter values and
gets back the result.
The value provided by CriteriaBase is that it includes the field manager so you can implement
properties as shown in this example, following the same basic structure as with any other business
type.

Using CSLA 4: Creating Business Objects Page 76


Rev 1.1
Using BusinessBase
It is also possible to create a criteria object by subclassing BusinessBase. In this case you are
literally using an editable object as a criteria object. The value of doing this is that an editable object
supports data binding and business rules.
If you are having the user enter the criteria values directly through the UI, it can be very
convenient to use data binding to connect the criteria object to the UI to collect the values. Even
better, you can use standard business rules to verify that the criteria values meet any requirements
or other rules.
Here’s the same criteria class, but as an editable object:
[Serializable]
public class CustomerCriteria : BusinessBase<CustomerCriteria>
{
public static PropertyInfo<int> RegionIdProperty = RegisterProperty<int>(c => c.RegionId);
public int RegionId
{
get { return GetProperty(RegionIdProperty); }
set { SetProperty(RegionIdProperty, value); }
}

public static PropertyInfo<int> CustomerIdProperty = RegisterProperty<int>(c => c.CustomerId);


public int CustomerId
{
get { return GetProperty(CustomerIdProperty); }
set { SetProperty(CustomerIdProperty, value); }
}
}

The only real difference is in the property implementations, which are now standard read-write
properties. I’ve also removed the constructor, because the idea is that these property values will be
set by the user through data binding.
Whether you use CriteriaBase or BusinessBase, the central point I’m making is that if your
criteria consists of multiple values, you need to create a serializable type to contain those values.

LINQ Types
CSLA 4 collection objects automatically work with LINQ to Objects, like any IEnumerable<T> in the
.NET framework.
The one problem with LINQ to Objects queries is that they return an IEnumerable<T>, which is
the most basic collection type in the .NET framework. This means that if you perform a query with
an identity projection (a query that returns the child objects from a collection) the result is a much
more primitive collection type than the one you had originally.
For example, suppose you have a CustomerInfoList read-only list, and you want to sort that list:
var sorted = from r in _customerList
orderby r.Name
select r;

The original _customerList field is a CustomerInfoList, which fully supports data binding and
provides all the other services and features of a ReadOnlyListBase object. The query result, the
sorted field, is a simple IEnumerable<T> and doesn’t support data binding or any of the features of
a read-only list.
Using CSLA 4: Creating Business Objects Page 77
Rev 1.1
This is even more confusing if you start with an editable list object. In that case, your query will
also return a simple IEnumerable<T> that doesn’t support data binding. But worse, if you add or
remove items from the query result they are not added or removed from the original list. It is that
original list that will be saved through the data portal!
Sometimes these issues aren’t a problem. Sometimes you need a sorted or filtered version of the
original list and you won’t bind it to a UI or otherwise manipulate the result of the query. But if you
do need to use the result of the query for data binding or manipulation, CSLA 4 includes a solution:
the LinqObservableCollection type.

LinqObservableCollection
The LinqObservableCollection class is an “intelligent wrapper” around a LINQ query result. It
creates a view over the original list based on the query result that supports data binding. Even
better, when you add or remove items from a LinqObservableCollection, those items are
automatically added or removed from the original list.
There are several ways to create a LinqObservableCollection, but the most common
technique is to use the ToSyncList extension method provided by CSLA 4. Alter the previous query
like this:
var sorted = (from r in _customerList
orderby r.Name
select r).ToSyncList(_customerList);

The sorted field is now a LinqObservableCollection that provides a “live view” over the
original collection. You get the same basic result, which is that the original collection has been
sorted, but this result supports data binding, change notification, and when items are added or
removed from the sorted field, they are automatically added or removed from _customerList as
well (assuming _customerList is an editable list).
Another way to create a LinqObservableCollection is to explicitly create the object:
var tmp = from r in _customerList
orderby r.Name
select r;
var sorted = new LinqObservableCollection<CustomerEdit>(_customerList, tmp);

The result of this code is the same as the previous example, I’m explicitly doing by hand what the
ToSyncList extension method did in the previous example. This example probably shows more
clearly that the LinqObservableCollection combines the original source list and the query result
to create a live view of the original list based on the query results.
You can use LinqObservableCollection to filter and sort any ObservableCollection<T>,
including those created with BusinessListBase and ReadOnlyListBase from CSLA .NET.

Windows Forms Types


Before WPF was introduced in .NET 3.0 most smart client applications were created using Windows
Forms. The Windows Forms technology laid the groundwork for most of the data binding concepts
we know today, but when WPF was introduced Microsoft decided to replace the interfaces and
related BindingList<T> base class with a new interface and ObservableCollection<T> type for
bindable collections.
Using CSLA 4: Creating Business Objects Page 78
Rev 1.1
Windows Forms pre-dates WPF and its ObservableCollection, so you can’t bind an
ObservableCollection to a Windows Forms UI and get the behaviors you’d expect. Windows
Forms data binding only works properly with BindingList collections.
On the other hand, WPF only works properly with ObservableCollection collections. It works to
some degree with BindingList collections, but you give up normal sorting and filtering capabilities
that are automatic with ObservableCollection types.
As developers, this puts us in an awkward situation; because we can choose to create a
collection that works with Windows Forms, or with WPF, but not both.
ASP.NET works with either collection base class. Silverlight and WP7 don’t even have the concept
of a BindingList, and only support ObservableCollection types. Table 16 lists which types work in
which UI technologies.

UI technology Collection type


WPF ObservableCollection
BindingList (partial functionality)
Silverlight ObservableCollection

WP7 ObservableCollection

Windows Forms BindingList

ASP.NET Web Forms ObservableCollection


BindingList
ASP.NET MVC ObservableCollection
BindingList
WCF service ObservableCollection
BindingList
asmx service ObservableCollection
BindingList
Windows Workflow ObservableCollection
BindingList
Console ObservableCollection
BindingList

Table 16. Collection types and UI technologies


In summary, ObservableCollection works everywhere except Windows Forms, while
BindingList doesn’t work in any modern XAML-based UI technology.

In CSLA 4 the default collection base types inherit from ObservableCollection, including:

 BusinessListBase
 ReadOnlyListBase
 DynamicListBase
 NameValueListBase

Using CSLA 4: Creating Business Objects Page 79


Rev 1.1
These types can be used to support all UI technologies except Windows Forms. If you are
building a collection that must be data bound to a Windows Forms UI, you’ll need to use the
alternative base types provided by CSLA 4:

 BusinessBindingListBase
 ReadOnlyBindingListBase
 DynamicBindingListBase

It is not ideal that a business layer developer must choose a collection type based on the UI
technology that will be using the collection. Unfortunately, Microsoft’s shift from BindingList to
ObservableCollection leaves us with no realistic alternative.

BusinessBindingListBase
The BusinessBindingListBase type supports the editable list stereotype in exactly the same way
as the BindingListBase class. Other than using a different base class in your business collection
code, your collection code will be the same.
Any code that interacts with a BusinessBindingListBase subclass will find some differences in
terms of supported events and data binding behaviors, because this is ultimately a subclass of
BindingList, which supports Windows Forms data binding.

DynamicBindingListBase
The DynamicBindingListBase type supports the editable list stereotype in exactly the same way as
the DynamicListBase class. Other than using a different base class in your business collection code,
your collection code will be the same.
Any code that interacts with a DynamicBindingListBase subclass will find some differences in
terms of supported events and data binding behaviors, because this is ultimately a subclass of
BindingList, which supports Windows Forms data binding.

ReadOnlyBindingListBase
The ReadOnlyBindingListBase type supports the editable list stereotype in exactly the same way
as the ReadOnlyListBase class. Other than using a different base class in your business collection
code, your collection code will be the same.
Any code that interacts with a ReadOnlyBindingListBase subclass will find some differences in
terms of supported events and data binding behaviors, because this is ultimately a subclass of
BindingList, which supports Windows Forms data binding.

At this point, in the ebook you should understand the stereotypes supported by CSLA 4, along
with the base classes you will use to implement business classes for each stereotype. The code in
your business classes relies on the property implementation, metastate, serialization and other
concepts discussed in Chapters 1 and 2.
I’ll now conclude the ebook by discussing how you can implement and use business rules in
editable objects, and authorization business rules in editable and read-only objects.

Using CSLA 4: Creating Business Objects Page 80


Rev 1.1
Using CSLA 4: Creating Business Objects Page 81
Rev 1.1
Chapter 4:
Business Rules
One of the primary features of CSLA 4 is the new business rules system that allows you to write
several different types of rules. The goal is to allow you to easily maintain all your business logic in
the business layer, which is composed of business domain objects created using the stereotypes
discussed in Chapter 3.
The editable child and root object stereotypes support all the types of rule I’ll discuss in this
chapter. Most other stereotypes only support authorization rules, and some stereotypes don’t
support rules at all (CriteriaBase doesn’t support any rules for example).
Table 17 lists the types of rules you can implement using the CSLA 4 rules system.

Type of rule Description


Validation Validation rules check one or more properties to see if the values
are valid according to the rule. These rules may be synchronous
or asynchronous and can indicate the property is in error, has a
warning, or should display an informational message.
DataAnnotations validation The System.ComponentModel.DataAnnotations namespace
includes a ValidationAttribute base class that allows you to create
custom validation attributes. These are supported by CSLA 4 and
are executed along with other validation rules.
Business Business rules alter one or more property values based on the
algorithm or behavior implemented by the rule. These rules can
take input values, do processing, and alter property values as a
result. They may be synchronous or asynchronous.
Per-object business and Per-object business and validation rules are like normal business
validation and validation rules, but they are not attached to any specific
property. Instead they are attached to the business object itself.
This type of rule is usually complex or expensive in terms of
computation or data access.
Property and method Per-property authorization rules check to see if the current user is
authorization allowed to read a property, write to a property, or execute a
method. These rules are checked on access to the property or
method, and allow or deny access to the user.
Business type authorization Per-type authorization rules check to see if the current user is
allowed to create, get, edit, or delete instances of the business
object type. These rules are checked by the data portal to
determine whether the user is allowed to perform the requested
action.

Table 17. Types of business rule supported by CSLA 4


In most cases rules are executed automatically by CSLA .NET. For example, when a user attempts
to get or set a property value the appropriate authorization rules are executed to see if the user
Using CSLA 4: Creating Business Objects Page 82
Rev 1.1
should be allowed to perform the operation. When a property is changed in an editable object the
business and validation rules associated with that property are executed, along with rules
associated with properties designated as being dependent on the changed property.
This includes any DataAnnotations attributes. They are considered to be validation rules, no
different from other CSLA 4 validation rules. What is interesting about DataAnnotations attributes
is that they are sometimes also executed by certain UI technologies. For example, ASP.NET MVC
and the Silverlight DataForm control both execute DataAnnotations attributes on your behalf. The
point of having CSLA .NET execute them, is that this way you know for sure that they are executed,
regardless of the type of UI or UI control you use to build your application.
The CSLA 4 rules system is designed to be easy to understand and use, and yet very powerful and
flexible. Most applications have rules that are pretty straightforward, and will be easy to
implement. Other applications may want to leverage external rules engines, or build rules in the
form of workflows or other technologies. These things are possible, but are obviously more complex
than “normal” rules.
In this chapter I’ll start each topic by discussing the straightforward approach, and then I’ll
discuss the concepts you’ll need to understand to implement more advanced and complex
scenarios.
I’ll discuss business and validation rules first, followed by authorization rules. While all rules are
very similar, there are enough differences between these types of rule that I’ll cover them
separately.

Business and Validation Rules


Business and validation rules are implemented and executed in the same way within CSLA 4.
Validation rules indicate whether a property has an error, warning, informational message, or is
valid. Business rules alter property values and don’t validate property values.
You should use validation rules or DataAnnotations attributes to validate any properties in your
editable objects. This will lead to very consistent and maintainable code for validation. As you’ll see
in the rest of the Using CSLA 4 ebook series, the validation rules you implement in your business
objects can be expressed to the user in every type of UI technology, with the exception of certain
ASP.NET applications. So for the most part this means you should expect to write your validation
logic one time in the business classes, and not have to replicate that logic in the presentation layer.
You should use business rules to alter property values in your objects based on any sort of rule,
algorithmic process, or calculation. Business rules can do something as simple as upper-casing a
string value, or as complex as performing a tax, price, or discount calculation.

Business and validation rules can interact with other business objects if necessary.
For example, you might implement a validation rule that determines whether an object’s id
value already exists in the database. To do this your rule will use a command object to interact with
the server, and if the value exists will probably return a warning or error message to indicate that
the property value already exists.
Another example would be a business rule that uses a read-only object to retrieve some values
from a massive database table, so the rule can use those values as part of its algorithmic processing.
Using CSLA 4: Creating Business Objects Page 83
Rev 1.1
Because rules might use other objects, some rules will be asynchronous. Remember that
Silverlight requires that all server interaction be asynchronous, and so any rule that uses an object
which must execute code on the server must support that asynchronous operation. The way rules
are implemented in CSLA 4 allows you to use the same basic coding structure for synchronous and
asynchronous rules, though there are certain limitations on asynchronous rules to help you avoid all
the potential complexity that comes with asynchrous and parallel processing.

Associating Rules with Properties and Types


Business and validation rules may be associated with properties or business types. Most rules are
associated with properties, but some rules apply to many properties (or to no properties) and so
must be associated with a business type instead of a specific property.
There are two ways to associate rules with properties or types. You can create the rules as
DataAnnotations attributes and apply the attribute to your business class or property, or you can
create the rule as a CSLA 4 IBusinessRule and associate the rule to a property or business class by
overriding the AddBusinessRules method in your editable root or child class.

Using DataAnnotations Attributes


If your rule is a DataAnnotations attribute it will be a subclass of ValidationAttribute. I’ll discuss
how to create such rules later in this chapter, but to use these attributes is as simple as applying the
attribute to your class or property. For example:
public static readonly PropertyInfo<string> NameProperty = RegisterProperty<string>(p => p.Name);
[Required]
public string Name
{
get { return GetProperty(NameProperty); }
set { SetProperty(NameProperty, value); }
}

The Required attribute is a standard attribute from the DataAnnotations namespace, and
indicates that this is a required property.
None of the standard DataAnnotations validation attributes are designed to apply to a business
class, but you might create your own validation attributes that are designed for that purpose. In
such a case, you’ll apply the attribute to your class declaration.
These attributes are included in the list of validation rules for the object by CSLA .NET by the
implementation of the AddBusinessRules method found in the BusinessBase class. If you override
AddBusinessRules you should make sure to call the base implementation to ensure validation
attributes are used properly by CSLA .NET.

Using AddBusinessRules
If your rule is a CSLA .NET rule it will implement IBusinessRule or be a subclass of BusinessRule,
both of which are found in the Csla.Rules namespace. I’ll discuss how to create such rules later in
this chapter.
You associate these rules with your properties or business class by overriding the
AddBusinessRule method in your editable root or child business class. For example:

Using CSLA 4: Creating Business Objects Page 84


Rev 1.1
protected override void AddBusinessRules()
{
base.AddBusinessRules();
BusinessRules.AddRule(new Csla.Rules.CommonRules.Required(NameProperty));
BusinessRules.AddRule(new MyClassRule());
}

This example adds a Required rule from the Csla.Rules.CommonRules namespace, and
associates the rule with the Name property. Notice the use of the static metadata field
NameProperty.

Also notice that a rule is an object, and this code creates an instance of that rule object. This one
rule instance is shared across all instances of the business type. This code creates a single Required
rule instance, and that instance is reused by every business object created for this specific business
class.
Every rule can have a primary property to which the rule applies or is associated. Rules that
require a primary property should require that property be provided to the rule’s constructor. The
Required rule follows this recommendation, requiring the primary property be specified as the rule
is created.
The example also adds a MyClassRule rule to the business class itself. Notice that the
MyClassRule doesn’t require that a primary property be provided to the constructor, so the rule
isn’t associated with any particular property. This tells CSLA .NET to associate the rule with the
business type itself.

Rule Priorities
By default rules are all added at the same priority and you can’t predict the order in which the rules
will be executed. This isn’t always ideal, because you might need certain rules to run before other
rules.
As you add rules to your properties or business type in your AddBusinessRules override you can
specify priority values for each rule. For example:
protected override void AddBusinessRules()
{
base.AddBusinessRules();
BusinessRules.AddRule(new Csla.Rules.CommonRules.Required(NameProperty) { Priority = 0 });
BusinessRules.AddRule(new ToUpper(NameProperty) { Priority = 1 });
}

In this example I’m associating two rules with the Name property. The Required rule is at priority
0, which is the default. The ToUpper rule is at priority 1, and so it will run after the Required rule.
Priority values are an int, and rules are executed from smallest to largest value, with the default
being 0.
Multiple rules can have the same priority, and by default all rules are at priority 0. Rules within
each priority will run in an indeterminate order. This means you can’t predict the order in which the
rules will be run. If you need to ensure that one rule runs before another rule you should explicitly
set the rule priorities.

Using CSLA 4: Creating Business Objects Page 85


Rev 1.1
Asynchronous rules are always started after all synchronous rules. All asynchronous rules are
started at the same time, and they’ll complete in an indeterminate order. There is no provision in
CSLA .NET for controlling the order of execution of asynchronous rules.
It is a good idea to add asynchronous rules at priority 1 or higher. This will prevent the
asynchronous rules from starting if any of the synchronous validation rules at priority 0 (the default
priority) fail. In most cases you won’t want to run the asynchronous rules unless all the basic
validation rules have passed. I’ll discuss short-circuiting rules in the next section of this chapter.
All DataAnnotations validation attributes are always at priority 0. The DataAnnotations
attributes have no concept of priority, so there’s no way to specify different priorities for these
attributes.

Short-Circuiting Rules
Closely related to the idea of rule priority is short-circuiting. The idea here is that you might want to
run your inexpensive rules first, and only run more expensive rules if the inexpensive ones don’t
mark the property as invalid.
For example, a Required rule is quite inexpensive because it only checks to see if a string value
has a non-zero length. But that same property might have a rule that runs code on the application
server to talk to the database to verify the property value. That’s clearly more expensive because it
requires interacting with servers and the database. There’s probably no value in verifying an empty
value against the database, so if the Required rule fails you don’t want to run the more expensive
rule.
By default, CSLA .NET will execute all rules with priority 0 or less (so all rules with negative
priorities and priority 0). Rules at priority 1 and higher will only execute if all validation rules at
priority 0 or smaller pass. If the property has been marked as invalid by the time priority 1 rules
would run, they won’t be executed.
The priority at which automatic short-circuiting starts is controlled by the
ProcessThroughPriority value, and you can change that value in the AddBusinessRules override:
protected override void AddBusinessRules()
{
BusinessRules.ProcessThroughPriority = 5;
base.AddBusinessRules();
}

In this example I’ve changed the value to 5, so in instances of this particular business class rules
at priority 5 or less will always execute, and those at priority 6 and higher will only run if no
validation rule has failed.
One common use of short-circuiting is to prevent rules from executing if the user isn’t even
allowed to write to the property. I’ll discuss authorization rules later in this chapter, but for this
discussion it is enough to understand that it is possible to prevent a user from writing to a property.
The following rule uses the CanWriteProperty method on the Target object to determine
whether the user is authorized to write to the specified property:
public class StopIfNotCanWrite : Csla.Rules.BusinessRule
{
public StopIfNotCanWrite(Csla.Core.IPropertyInfo property)

Using CSLA 4: Creating Business Objects Page 86


Rev 1.1
: base(property)
{ }

protected override void Execute(RuleContext context)


{
var target = (Csla.Core.BusinessBase)context.Target;
if (!target.CanWriteProperty(context.Rule.PrimaryProperty))
context.AddSuccessResult(true);
}
}

If the user isn’t authorized, the AddSuccessResult method is invoked, passing a parameter value
of true to trigger explicit short-circuiting. In that case, no more rules will be executed for this
property.
Adding this rule to a property at a priority of -1 will cause it to run before all the rules added at
the default priority of 0 or higher:
protected override void AddBusinessRules()
{
base.AddBusinessRules();
BusinessRules.AddRule(new StopIfNotCanWrite(OrderDateProperty) { Priority = -1 });
}

At this point, you should understand how to associate rules with properties or business classes,
as well as how to control the order of rule execution using priorities and short-circuiting.

Rule Sets
Some applications are designed for use in shared hosting environments. Such an application runs on
a server, and it is used by users who don’t work for the same organization. This model is quite
common in software as a service scenarios, where the application is centrally hosted, but is made
available to numerous unrelated customers.
In such a case it is possible that different customers will have different business rule
requirements. A given business object might have one set of rules for one customer, and a different
set of rules for another customer.
To accommodate this type of situation, CSLA .NET has a concept called rule sets. In my examples
so far, all the calls to the AddRule method in the AddBusinessRules override have added rules to
the default rule set. Because most applications will have only one set of rules, this is a good default
behavior.
If your application has multiple rule sets, you’ll need to specify the rule set before calling the
AddRule method. And you’ll need to add all the rules for each rule set individually. For example:
protected override void AddBusinessRules()
{
base.AddBusinessRules();

// add rules to default rule set


BusinessRules.AddRule(new Csla.Rules.CommonRules.Required(NameProperty) { Priority = 0 });
BusinessRules.AddRule(new ToUpper(NameProperty) { Priority = 1 });

// add rules to rule set A


BusinessRules.RuleSet = "RuleSetA";
BusinessRules.AddRule(new Csla.Rules.CommonRules.Required(NameProperty) { Priority = 0 });
BusinessRules.AddRule(new ToUpper(NameProperty) { Priority = 1 });

// add rules to rule set B

Using CSLA 4: Creating Business Objects Page 87


Rev 1.1
BusinessRules.RuleSet = "RuleSetB";
BusinessRules.AddRule(new Csla.Rules.CommonRules.Required(NameProperty) { Priority = 0 });
BusinessRules.AddRule(new ToUpper(NameProperty) { Priority = 1 });

// use default rule set


BusinessRules.RuleSet = "default";
}

While this code is setting the same rules into each rule set, a real application would load only
appropriate rules into each rule set based on your business requirements.
The first two rules are added to the default rule set, because the RuleSet property hasn’t been
specified. Then I change the RuleSet property to “RuleSetA” and add a couple rules to that rule set.
The same is done for “RuleSetB”. Finally the RuleSet property is set to “default” so the application
will use the default rule set.
The RuleSet property controls the rule set used by this specific business object, allowing you to
change the rule set for each specific business object. You will typically do this based on the state of
the business object. For example, business objects created or retrieved for Customer A will use the
rule set for that customer, while business objects created or retrieved for Customer B will use a
different rule set. You’ll normally set the RuleSet property for an object as part of its data access
code when the object is created or retrieved.

Executing Rules
Business and validation rules are associated with either a property or to a business object. Most
rules are associated with properties. These rules only apply to the editable object stereotype, and
so are only available to objects that subclass BusinessBase.

Per-Property Rules
Rules that are associated with properties are automatically executed by the SetProperty and
SetPropertyConvert methods. If you follow the property implementation guidelines from Chapter
1, this means your rules will run automatically as properties are changed.
The LoadProperty and LoadPropertyConvert methods do not execute rules.
It is possible to suppress rules so they aren’t automatically executed by SetProperty or
SetPropertyConvert. I’ll discuss how to suppress rule execution later in this chapter.

If you are using one of the DataPortal_XYZ data access models (covered in the Using CSLA 4:
Data Access ebook) the rules are also automatically invoked when the business object is created.
The base implementation of DataPortal_Create runs all rules associated with all properties and the
business type as the object is created.

Dependent Properties
The SetProperty and SetPropertyConvert methods automatically execute business and validation
rules when a property’s setter is called. It is possible to tell CSLA .NET that a relationship exists
between properties in your object, indicating that some properties are dependent on other
properties. After rules for a property are executed, any rules associated with dependent properties
are also executed.

Using CSLA 4: Creating Business Objects Page 88


Rev 1.1
For example, in a change password dialog you’ll often require that the user enter their new
password twice. And you’d have a rule that checks to make sure both password values match. If the
user mis-types their new password they could fix the value by retyping the password in either of the
input controls of the UI. This means the NewPassword1 and NewPassword2 properties of your
business object are dependent on each other. Any time rules are run for one property, they should
be run for the other as well.
As another example, in a SalesOrderEdit class you might have a CreditLimitOverride
property. If this value is set, it means the user has overridden the customer’s normal credit limit,
and you might require that they enter another value to confirm that they meant to perform the
override. This ConfirmOverride property would be dependent on the CreditLimitOverride
property.
Rules can affect multiple properties, even though each rule has exactly zero or one primary
properties. I’ll discuss this more when I show you how to create your own rules. If a rule affects
multiple properties, CSLA .NET will automatically consider all affected properties to be dependent
on the primary property. For example:
protected override void AddBusinessRules()
{
base.AddBusinessRules();
BusinessRules.AddRule(
new CalculateTotal(Value1Property, Value2Property, Value3Property));
}

This CalculateTotal rule requires that three properties be provided in its constructor. Let’s
assume it adds Value1 and Value2 and puts the result in Value3. This means Value3 is affected by
this rule, so when rules are executed for the Value1 property, all the rules for the Value3 property
will also be executed.
You should understand that all rules for the primary property are executed first, in priority order.
Then rules are run for each dependent property, one property at a time. The rules for each
dependent property are also executed in priority order.
Any asynchronous rules for each property are started after all synchronous rules for that
property are complete. Because asynchronous rules are asynchronous, their executions will likely
overlap, and you need to take that into consideration when implementing any asynchronous rules.
CSLA .NET provides a rule designed specifically to set up dependency relationships between
properties. In many cases, dependencies are automatically detected because properties affected by
a rule become dependent properties. But sometimes you’ll want to explicitly designate a
dependency relationship by using the Dependency rule:
protected override void AddBusinessRules()
{
base.AddBusinessRules();
BusinessRules.AddRule(
new Csla.Rules.CommonRules.Dependency(CreditLimitOverrideProperty, ConfirmOverrideProperty));
}

The Dependency rule is found in the Csla.Rules.CommonRules namespace, and it requires a


primary property, along with a list of dependent properties. In this example the primary property is
CreditLimitOverride, and the dependent property is the ConfirmOverride property. This means

Using CSLA 4: Creating Business Objects Page 89


Rev 1.1
that any time rules are executed for CreditLimitOverride, the rules for ConfirmOverride will be
executed as well.

Per-Type Rules
Rules associated with a business type are only automatically executed when you use one of the
DataPortal_XYZ data access models (covered in the Using CSLA 4: Data Access ebook). In this case
the rules are automatically invoked when the business object is created. The base implementation
of DataPortal_Create runs all rules associated with all properties and the business type as the
object is created.
Other than this one scenario, you always need to manually cause the execution of per-type rules
by calling either CheckRules or CheckObjectRules on the BusinessRules object as discussed in the
next section of this chapter.

Manually Executing Rules


There are times when you will need to explicitly trigger the execution of some or all the rules for
your object. Some examples include:

 After loading the object with data from the database, when you don’t trust the data from
the database
 When a data portal request from a client arrives at your web or application server and you
want to rerun rules because you are concerned the client intetrigty has been compromised
 On a ChildChanged event when a parent object needs to run rules based on changes to a
child object

As I’ve mentioned, the BusinessBase class has a protected property named BusinessRules.
This BusinessRules object includes methods you can use to invoke rules as described in Table 18.

Method Description
CheckRules Executes all rules for the object and for all properties of the
object
CheckRules(property) Executes rules for the specified property, followed by rules for
any dependent properties
CheckObjectRules Executes per-type rules for the object

Table 18. Methods used to manually execute rules


You can use these methods when you need to manually execute rules within your object.
It is also possible to use the ICheckRules interface from the Csla.Core namespace to invoke
rules on other objects. This interface is intended for use by UI framework developers building UI
code for block-mode interfaces (such as web or service interfaces). You may find other uses for this
interface, but you must be careful because this does break encapsulation and widespread use (or
misuse) of this interface can quickly lead to very unmaintainable code.

Using CSLA 4: Creating Business Objects Page 90


Rev 1.1
The ICheckRules interface has a CheckRules method you can call, and it calls the CheckRules
method of BusinessRules for the specific business object. It runs all per-type and property rules for
the object.

Executing Rules in Parent Objects


There are times when you’ll want to execute a rule in a parent object based on the fact that a child
object has been changed. For example, a SalesOrderEdit parent object may need to recalculate its
total cost value as its child LineItemEdit objects are added, removed, and changed.
To do this, you should implement the rule and associate it with a property of the parent business
type. But you also need to make sure the rule is executed each time a child object is changed, and
to do that you’ll need to override the OnChildChanged method in the parent business class. For
example:
protected override void OnChildChanged(Csla.Core.ChildChangedEventArgs e)
{
base.OnChildChanged(e);
BusinessRules.CheckRules(SalesOrderEdit.LineItemsProperty);
}

The OnChildChanged method (and corresponding ChildChanged event) execute each time a child
object is changed within the object graph. You can use the ChildChangedEventArgs parameter to
get specifics about the change, which can be useful when you only want to call CheckRules when
certain child objects are changed.
In this example, when OnChildChanged is invoked the code calls CheckRules to run all rules
associated with the LineItems property, ensuring that those rules are executed each time a child
object is changed.

Suppressing Rule Execution


Sometimes you’ll need to prevent the normal execution of business, validation, and authorization
rules. The two primary scenarios where it is important to suppress rules are during data access or
object persistence, and in block mode interfaces such as most web and service interfaces.
In the data access scenario, you are typically setting or getting property values as those values
are loaded from the database or stored into the database. You’ll rarely want to run rules during this
process because the data in the database is often assumed to be valid, or because the rules were
already run as the user interacted with the business object. Re-running the rules during persistence
leads to complexity and performance issues.
In the block mode interface scenario, the user has typically entered many values in a web UI, or a
whole set of values has been provided as part of a call to your service. Either way, you have a whole
set of values that will be placed into the properties of your business object. It is often more efficient
to temporarily suppress all rule checking, load all the property values, and to then explicitly run all
the rules for the object.
There are three ways you can prevent or suppress rules from running when SetProperty or
SetPropertyConvert are invoked. These are listed in Table 19.

Using CSLA 4: Creating Business Objects Page 91


Rev 1.1
Technique Description
BypassPropertyChecks The BusinessBase class has a protected member called
BypassPropertyChecks that is designed for use in a using block. All
code within a using (BypassPropertyChecks) code block will have
rule execution suppressed, so no business, validation, or authorization
rules will be run.
using (BypassPropertyChecks)
{
// set properties here without executing
// any rules
}

This technique is designed for use within data access code and I’ll use this
technique in the Using CSLA 4: Data Access ebook. If you are using what
are called DataPortal_XYZ methods you’ll write code like I’m showing
here. If you are using the ObjectFactory data access technique the
ObjectFactory base class from the Csla.Server namespace also has a
BypassPropertyChecks method to provide similar functionality.
ICheckRules The BusinessBase class implements the ICheckRules interface from
the Csla.Core namespace. This interface defines methods that allow
code to suppress rule execution, resume rule execution, and to force
execution of all business and validation rules.
((Csla.Core.ICheckRules)_customer).SuppressRuleChecking();
try
{
// set properties here without executing
// any rules
}
finally
{
((Csla.Core.ICheckRules)_customer).ResumeRuleChecking();
((Csla.Core.ICheckRules)_customer).CheckRules();
}

The purpose of the ICheckRules interface is to support UI frameworks,


specifically for block mode interfaces such as those created with ASP.NET
Web Forms, ASP.NET MVC, asmx services, and WCF services. The code
I’m showing here would typically be written in the code handing a web
postback, a controller method, or in a service implementation.
SuppressRuleChecking The BusinessBase class has a protected member called
BusinessRules that you will use to interact with the business rules for
each object. The BusinessRules object has a SuppressRuleChecking
property you can set to true to suppress rules, and false for normal
operation.
BusinessRules.SuppressRuleChecking = true;
try
{
// set properties here without executing
// any rules
}
finally
{
BusinessRules.SuppressRuleChecking = false;

Using CSLA 4: Creating Business Objects Page 92


Rev 1.1
}

This SuppressRuleChecking property is used by the


BypassPropertyChecks and ICheckRules techniques, so you can
consider this to be the lowest level technique.

Table 19. Techniques for suppressing business rule execution


The most common case where you will suppress rule checking is during object persistence as you
load and save data from your object. The BypassPropertyChecks technique is commonly used to
address that requirement.
Somewhat less common is where a block mode UI needs to suppress and trigger rule execution
using ICheckRules.
In any case, you can use these techniques as required by your application to suppress and trigger
rule execution.
You should now understand how rules are associated with properties, property dependencies,
and how and when rules are executed. I’ll move on to discuss how you create business rules and
validation rules.

Implementing Business and Validation Rules


Business and validation rules use the same base types and follow the same implementation
structure. The difference is that business rules change property values, while validation rules return
error, warning, or information results.

Structure of a Rule
A business or validation rule is implemented as a class that implements the IBusinessRule
interface or inherits from the BusinessRule base class defined in the Csla.Rules namespace. While
there are many ways you can implement rules and a lot of advanced features at your disposal, the
basic structure of a rule class is pretty consistent.
For example, here’s a rule that must be associated with a business object property:
public class MyRule : Csla.Rules.BusinessRule
{
public MyRule(Csla.Core.IPropertyInfo primaryProperty)
: base(primaryProperty)
{
InputProperties = new List<Csla.Core.IPropertyInfo> { PrimaryProperty };
}

protected override void Execute(Csla.Rules.RuleContext context)


{
object input = context.InputPropertyValues[PrimaryProperty];
// implement rule here
}
}

Here is a similar rule that changes the value of the primary property associated with the rule:
public class MyRule : Csla.Rules.BusinessRule
{
public MyRule(Csla.Core.IPropertyInfo primaryProperty)
: base(primaryProperty)
{
Using CSLA 4: Creating Business Objects Page 93
Rev 1.1
InputProperties = new List<Csla.Core.IPropertyInfo> { PrimaryProperty };
}

protected override void Execute(Csla.Rules.RuleContext context)


{
object input = context.InputPropertyValues[PrimaryProperty];
// implement rule here
context.AddOutValue("new value");
}
}

You can use the AddOutValue method shown here to have the rule change the primary
property’s value when the rule completes. The AddOutValue method can also be used to change
other property values. In that case you must add those properties to the AffectedProperties list in
the rule’s constructor. I’ll discuss the AffectedProperties list later in this chapter.
While most rules are associated with a property, that’s not true of all rules. Here’s another
example, of a rule that doesn’t require that it be associated with a property:
public class MyRule : Csla.Rules.BusinessRule
{
protected override void Execute(Csla.Rules.RuleContext context)
{
// implement rule here
}
}

Because no primary property is required by this rule’s constructor, the rule may or may not be
associated with a specific property. That decision is deferred to your code in the AddBusinessRules
override of the business class.
The rule classes inherit from the BusinessRule base class. You could choose to implement the
IBusinessRule interface manually, though this is an advanced scenario that should be extremely
uncommon.
When a rule requires an associated property, or other input values, it will implement a
constructor to require those values. Rules that don’t require such input won’t have an explicit
constructor.
The implementation of the rule is always in the Execute method, which is provided with a
RuleContext parameter. This parameter contains input values and provides mechanisms for rules
to provide output results.

RuleContext Parameter
Central to any business or validation rule implementation is the RuleContext parameter that is
provided to the Execute method. The RuleContext parameter value contains the members listed in
Table 20.

Member Description
Rule Gets a reference to the business rule object
Target Gets a reference to the business object; defaults to null
for async rules unless you set
ProvideTargetWhenAsync to true in the rule’s
constructor

Using CSLA 4: Creating Business Objects Page 94


Rev 1.1
InputPropertyValues Gets a dictionary containing input property values from
the business object; the properties provided are defined
in the InputProperties list you set in the rule’s
constructor
OutputPropertyValues Gets a dictionary containing output property values
resulting from this rule; you’ll normally use the
AddOutValue method instead of directly altering this
dictionary
GetChainedContext Gets a chained RuleContext object you can provide to a
rule you invoke from your rule (I’ll discuss rule chaining
later in this chapter)
AddErrorResult Adds a validation error result to the output of the rule
AddWarningResult Adds a validation warning result to the output of the rule
AddInformationResult Adds a validation informational result to the output of
the rule
AddSuccessResult Adds a validation success result to the output of the rule
AddOutValue Adds a property value to the output of the rule; these
values will be used to update the properties once the
rule is complete; all properties used with AddOutValue
must be added to the AffectedProperties list in the
rule’s constructor
Complete Indicates that the asynchronous rule is complete so CSLA
.NET knows to process the rule’s results; not necessary
for synchronous rules

Table 20. Members provided by the RuleContext type


When creating business rules you’ll typically use the following members:

 InputPropertyValues
 AddOutValue
 Complete (async only)

When creating validation rules you’ll typically use the following members:

 InputPropertyValues
 AddErrorResult
 AddWarningResult
 AddInformationResult
 AddSuccessResult
 Complete (async only)

Using CSLA 4: Creating Business Objects Page 95


Rev 1.1
If you are willing to create strongly coupled rules that are directly aware of the business object
type you can make use of the Target property to get a reference to the business object. This should
be avoided to minimize coupling between your rules and your business types. Additionally, the
Target property can only be used on the UI thread and any use of this property on a background
thread will lead to cross-thread exceptions or nasty threading bugs.
The GetChainedContext method is used to create a new RuleContext object that can be passed
to another rule you explicitly invoke from within your rule’s Execute method. This allows one rule
to invoke other rules through a process called rule chaining. I’ll discuss rule chaining later in this
chapter.
I mentioned two base types that are important for implementing rules: IBusinessRule and
BusinessRule, both from the Csla.Rules namespace.

IBusinessRule Interface
All business rule types must implement the IBusinessRule interface. This interface is used by the
CSLA .NET business rules subsystem to interact with all business rules. You can implement this
interface directly if you choose, but I recommend using the BusinessRule base class for most rules.
The IBusinessRule interface defines the members listed in Table 21.

Member Description
PrimaryProperty Defines the primary property to which the rule is associated; if
null then the rule is associated with a business type.
RuleName Gets the unique name of the rule as a rule:// URI.
Priority Gets the priority of the rule.
IsAsync Gets a value indicating whether the Execute method will run
asynchronous code.
ProvideTargetWhenAsync Gets a value indicating whether the RuleContext should include
a Target value for an async rule. The default is false, because
use of the Target value in async code will cause serious
problems that are hard to identify and debug.
Execute The method that is invoked when the rule is executed. This is the
method that implements the rule.
InputProperties Gets a list of IPropertyInfo fields defining the property values
that should be provided to the Execute method through the
RuleContext parameter.
AffectedProperties Gets a list of properties that are affected by this rule. These are
considered to be dependent properties, and their rules are run
after the synchronous rules for the primary property are
complete. If your rule sets output values with the AddOutVaue
method, the output properties must be added to the
AffectedProperties list.

Table 21. Members defined in IBusinessRule interface

Using CSLA 4: Creating Business Objects Page 96


Rev 1.1
If you do choose to manually implement the IBusinessRule interface, I strongly recommend you
carefully examine the BusinessRule class to see how each member is implemented. That should
provide you with insight into how your code must work.

BusinessRule Base Class


The simplest way to create a business rule is to inherit from the BusinessRule base class in the
Csla.Rules namespace. This class implements the IBusinessRule interface and provides a simple
and accessible way to create business rules.
The BusinessRule class implements the members listed in Table 21, along with a couple extra
methods: LoadProperty and ReadProperty. These methods are extremely useful when
implementing rules that need to get and set property values on the business object.
The BusinessRule base class provides three major features:

 Automatic generation of a unique RuleName value


 LoadProperty method
 ReadProperty method

I’ll discuss each feature.

RuleName Property
Perhaps the most important behavior is that the BusinessRule base class automatically creates a
valid RuleName value for each rule object. The RuleName property must contain a rule:// URI that
uniquely identifies each specific rule object. Normally this URI will look something like those listed
in Table 22.

URI Description
rule://ruleType/null Rule associated with a business type
rule://ruleType/null?p1=v1 Rule associated with a business type, where the rule has
additional property values
rule://ruleType/primaryProperty Rule associated with a specific property
rule://ruleType/primaryProperty?p1=v1 Rule associated with a specific property, where the rule
has additional property values

Table 22. Examples of rule:// URI values


The ruleType value is the assembly qualified type name of the business rule class, so it can be
quite long and could contain invalid characters for a URI. This value is “fixed” by the RuleUri class in
the Csla.Rules namespace so it doesn’t contain any invalid characters, and won’t exceed the
maximum length for a URI value.
The primaryProperty value is the name of the primary property to which this rule is associated.
If the rule is associated with a business type instead of a property, the value will be “null”.
The RuleUri object that contains the URI for the RuleName property is a protected member of
the BusinessRule base class. You can access this value through the RuleUri property.
Using CSLA 4: Creating Business Objects Page 97
Rev 1.1
ReadProperty and LoadProperty Methods
In the rule examples you’ve seen so far, I’ve been using the InputProperties and AddOutValue
techniques to get and set property values on the business object. For most rules this is a good
approach, because that technique works for both synchronous and asynchronous rules. Also, that
technique doesn’t require that the rule have any specific knowledge about the business class
because the rule interacts with the property values it has been provided through the RuleContext
parameter.
Alternately, you might choose to implement your rule to directly interact with the business
object and its properties. This can be more direct and efficient, but can lead to tight coupling
between your rule implementation and a specific business class.
To do this, you’ll use the Target property of the RuleContext parameter within the Execute
method of your rule. You might try something like this alternative to the ToUpper rule example I
used earlier:
protected override void Execute(Csla.Rules.RuleContext context)
{
var target = (ProductEdit)context.Target;
target.Name = target.Name.ToUpper();
}

This won’t actually work, however. It is important to remember that the property getter and
setter code in a normal editable object uses GetProperty and SetProperty, and so all
authorization, business, and validation rules are executed automatically. Your rule is almost
certainly executing because the primary property was changed. In this case, if your code directly
sets the primary property, (in this example the Name property) you’ll end up in a recursive loop that
will ultimately cause a stack overflow exception.
To avoid this issue you must not directly use the property getter or setter to get or set property
values from the business object.
The purpose of the ReadProperty method provided by the BusinessRule class is to allow you to
get property values of the business object without triggering authorization rules. The purpose of the
LoadProperty method is to allow you to set property values of the business object without
triggering authorization, business, or validation rules.
The correct implementation to directly interact with the business object’s properties is this:
protected override void Execute(Csla.Rules.RuleContext context)
{
var target = (ProductEdit)context.Target;
var name = (string)ReadProperty(target, ProductEdit.NameProperty);
LoadProperty(target, ProductEdit.NameProperty, name.ToUpper());
}

Notice how the ReadProperty method is used to get the property value from the target object,
and then the LoadProperty method is used to set the property with a new value.
If you are implementing a rule that is tightly coupled to a specific business class, this is a good
technique to efficiently get and set properties from that object. You should make sure that no code
on any background thread ever tries to interact with the Target value or its properties.

Using CSLA 4: Creating Business Objects Page 98


Rev 1.1
Remember that direct interaction with the Target parameter from the RuleContext
parameter can only occur on the main UI thread. Accessing the Target value from a
background thread will result in cross-thread exeptions or other complex multi-
threading bugs.

For most rules you should use the InputProperties and AddOutValue technique to avoid tight
coupling and to provide consistent coding for both synchronous and asynchronous rules.

Rule State
Your rule might require that extra parameter values be provided to the rule as it is created. For
example, here’s a rule that adds some value to a numeric property:
public class AddValue : Csla.Rules.BusinessRule
{
public int ValueToAdd { get; private set; }

public AddValue(Csla.Core.IPropertyInfo primaryProperty, int valueToAdd)


: base(primaryProperty)
{
InputProperties = new List<Csla.Core.IPropertyInfo> { PrimaryProperty };
ValueToAdd = valueToAdd;
RuleUri.AddQueryParameter("ValueToAdd", valueToAdd.ToString());
}

protected override void Execute(Csla.Rules.RuleContext context)


{
var value = (int)context.InputPropertyValues[PrimaryProperty];
context.AddOutValue(PrimaryProperty, value + ValueToAdd);
}
}

In this rule, I have a ValueToAdd property that is set through the constructor, and that property
is used by the rule as it executes.
It is critical that you understand that instance properties or fields in a rule object can not be
changed after the rule object has been created.

You must initialize instance properties and fields as the object is created, and never
change them from that point forward.

This restriction exists because each rule object is shared by all instances of the business type
with which the rule is associated. If you did change a property or field in a rule, you’d instantly
affect all business objects using that rule, and the result would almost certainly be inconsistent
behavior that would be difficult to identify, debug and fix.
Earlier in this chapter I discussed the RuleName property and how it must be unique for each
rule. If your rule requires extra parameter values, you must ensure that those values are included in
the rule:// URI that defines the RuleName property, and you do this by adding your parameter
values to the RuleUri property of the BusinessRule base class.
Keep in mind that you could associate more than one instance of the AddValue rule to any
property, so to ensure that the rule name is unique, you must include this parameter value as part
of the RuleName, which means it must be part of the RuleUri value. The constructor adds this value
to the RuleUri:
Using CSLA 4: Creating Business Objects Page 99
Rev 1.1
RuleUri.AddQueryParameter("ValueToAdd", valueToAdd.ToString());

If you forget to add your parameters to the RuleUri, you run the risk of having more than one
rule with the same name associated with a property in your business object. That will lead to
inconsistent behaviors as rules are executed. Such inconsistencies will typically only be discovered if
you implement comprehensive unit testing for your properties and their rules.

It is technically still possible to have two rules with the same name associated with a
property if both rules have exactly the same parameter values. This is considered to
be an extreme edge case, and if you encounter such a scenario you will need to
devise your own way to identify each rule separately.

In summary, the two things you must remember when implementing instance level properties or
fields in a rule is that the property or field value must be added to the RuleUri, and that the
property or field value must not be changed once the object has been initialized.
Now I’ll switch gears and talk about a couple more advanced features of rules: rule chaining and
asynchronous rules.

Rule Chaining
Rule chaining enables one rule to invoke another rule. There are various reasons why you might use
rule chaining, including:

 Implementing a gateway rule


 Implementing a selector rule
 Devising your own model for rule invocation

Of these, the simplest and most common is the idea of a gateway rule. A gateway rule is a rule
that checks a condition to decide whether it should invoke the “real rule” or inner rule. I’ll use the
gateway rule as an example of rule chaining because this is the most common scenario.
For example, your business object might have a property that is required for existing objects, but
isn’t required for a new object. The rule is a simple required rule such as
Csla.Rules.CommonRules.Required, but it should only be executed if the business object’s IsNew
property is false. You can use a gateway rule to check IsNew, and to invoke the Required rule only
when appropriate:
public class IsNotNew : Csla.Rules.BusinessRule
{
public Csla.Rules.IBusinessRule InnerRule { get; private set; }

public IsNotNew(Csla.Core.IPropertyInfo primaryProperty, Csla.Rules.IBusinessRule innerRule)


: base(primaryProperty)
{
InputProperties = new List<Csla.Core.IPropertyInfo> { PrimaryProperty };
InnerRule = innerRule;
RuleUri.AddQueryParameter("rule", System.Uri.EscapeUriString(InnerRule.RuleName));
}

protected override void Execute(Csla.Rules.RuleContext context)


{
var target = (Csla.Core.ITrackStatus)context.Target;

Using CSLA 4: Creating Business Objects Page 100


Rev 1.1
if (!target.IsNew)
{
var chainedContext = context.GetChainedContext(InnerRule);
InnerRule.Execute(chainedContext);
}
}
}

It is important to understand that the gateway rule must ensure that its InputProperties list
includes all property values that will be required by the rule it invokes. The chained RuleContext
generated by the GetChainedContext method includes the property values specified by the outer
rule’s InputProperties list. One way to automate this process is by replacing the code in the
constructor with this variation:
public IsNotNew(Csla.Core.IPropertyInfo primaryProperty, Csla.Rules.IBusinessRule innerRule)
: base(primaryProperty)
{
InputProperties = new List<Csla.Core.IPropertyInfo> { PrimaryProperty };
InnerRule = innerRule;
RuleUri.AddQueryParameter("rule", System.Uri.EscapeUriString(InnerRule.RuleName));

// merge InnerRule input property list into this rule's list


if (InnerRule.InputProperties != null)
InputProperties.AddRange(InnerRule.InputProperties);
// remove any duplicates
InputProperties = new List<Csla.Core.IPropertyInfo>(InputProperties.Distinct());
}

Notice how the InputProperties list (if any) from the InnerRule object is merged into the
InputProperties list of the IsNotNew gateway rule.

The business class will associate this IsNotNew rule with a property in its AddBusinessRules
override like this:
protected override void AddBusinessRules()
{
base.AddBusinessRules();
BusinessRules.AddRule(
new IsNotNew(CityProperty, new Csla.Rules.CommonRules.Required(CityProperty)));
}

In this example, the IsNotNew rule is associated with the CityProperty, and the inner rule is also
provided. The inner rule is the Required rule from Csla.Rules.CommonRules. Based on the
implementation of the Execute method in the IsNotNew rule, you can see that the Required rule
will only execute if the business object’s IsNew property is false.
You can use this same concept to build outer rules that invoke one or more inner rules. The
important thing is to ensure that you create a unqiue chained context for each inner rule you
invoke, and to ensure that the outer rule’s InputProperties list contains any properties required
by the inner rules. This capability for one rule to invoke other rules can be used to create gateway
rules as I’ve shown here, but also to create rules that select which other rules to run, thus allowing
you to create your own rule execution model when necessary.

Asynchronous Rules
Business and validation rules can be synchronous or asynchronous. Generally speaking, all rules
follow the same code structure, but there are some important differences between synchronous
and asynchronous rules.
Using CSLA 4: Creating Business Objects Page 101
Rev 1.1
Asynchronous, parallel, or multi-threaded coding is complex. You should use
caution, and make sure you completely understand all the consequences before
creating an asynchronous rule.

Asynchronous rules aren’t automatically asynchronous. CSLA .NET doesn’t run the rule on a
background thread for you. Instead, an asyncrhronous rule is a rule that is allowed to execute
asynchronous, parallel, or multi-threaded operations within the rule implementation. It is your code
in the rule implementation that will call an asynchronous service, or will run some code on a
background thread (usually using the BackgroundWorker component). And it is your code that is
responsible for ensuring that the completion notification runs on the original calling thread
(typically the UI thread).
In other words, “asynchronous rules” are potentially asynchronous, and it is up to you whether
the rule is asynchronous or not. It is important to note that CSLA .NET treats asynchronous rules
differently from synchronous rules, because the framework assumes the rule will be asynchronous.
You indicate that a rule is asynchronous by setting the IsAsync property to true in the rule’s
constructor:
public BusinessRuleClass(IPropertyInfo primaryProperty)
: base(primaryProperty)
{
IsAsync = true;
}

If you set IsAsync to true as shown here, you are allowed to invoke asynchronous operations in
your Execute method implementation. One of the most common scenarios is to invoke an async
factory method on a business class. Here’s a rule that checks to see if a product number already
exists in the database:
public class ProjectExists : Csla.Rules.BusinessRule
{
public ProjectExists(Csla.Core.IPropertyInfo primaryProperty)
: base(primaryProperty)
{
IsAsync = true;
InputProperties =
new System.Collections.Generic.List<Csla.Core.IPropertyInfo> { PrimaryProperty };
}

protected override void Execute(Csla.Rules.RuleContext context)


{
var id = (Guid)context.InputPropertyValues[PrimaryProperty];
Project.Exists(id, (result) =>
{
if (result)
context.AddWarningResult("Project already exists");
context.Complete();
});
}
}

The Project.Exists method is an asynchronous factory method that invokes the data portal to
make an asynchronous call to the application server to see if the project id already exists in the
database. Notice how the callback handler is a lambda expression that checks the result value and
adds a warning result if the value is true.

Using CSLA 4: Creating Business Objects Page 102


Rev 1.1
Perhaps most importantly, notice the call to the Complete method of the RuleContext
parameter.

You must call Complete on the RuleContext when the asynchronous operation is
complete. If you don’t call Complete, CSLA .NET will never know that your rule has
completed.

The Complete method must be called in cases of success or failure. When the asynchronous
operation is complete, call the Complete method.
I’ve already discussed the difference in execution times between synchronous and asynchronous
rules. Synchronous rules are invoked according to priority order and are subject to short-circuiting.
Asynchronous rules are started after all synchronous rules for a property have been executed, and
they run in an indeterminate order. If you have multiple asynchronous rules, they will run in parallel
and will complete in an indeterminate order based on how long each rule takes to complete.
Synchronous rules have access to the business object instance, and can directly interact with the
object and its properties. By default asynchronous rules do not have access to the business object
instance, and must rely on CSLA .NET to provide the rule with copies of any property values
required by the rule.
Similarly, asynchronous rules can provide a dictionary of property values to be changed, and
CSLA .NET changes those property values after the rule completes. An asynchronous rule with a list
of AffectedProperties will cause rules for those properties to be executed when Complete is
called on the RuleContext, and after any output values have been updated on the target object.
The reason for these restrictions is that CSLA .NET is not threadsafe, which means you can’t have
multiple threads interacting with an object at the same time. Some or all code in an asynchronous
rule may be running on a background thread, so it is important that such code not interact directly
with the business object or its properties.

Using BackgroundWorker
The most common reason to create an asynchronous rule is because the rule needs to call an
asynchronous factory method or the asynchronous data portal. Another common scenario is where
a rule needs to implement some algorithm that will take a substantial amount of time (seconds or
minutes) to complete.
In this case, you’ll explicitly execute the long-running code on a background thread. The .NET 4
framework includes some nice features for implementing tasks on background threads in the
System.Threading.Tasks namespace. Unfortunately these features are not available in Silverlight
or WP7, so if you are writing code for all current platforms you’ll need to avoid using the Task
features of .NET 4.
I recommend using the BackgroundWorker component for several reasons:

 It provides easy access to background threads in the .NET thread pool


 It is available on .NET, Silverlight, and WP7
 It automatically puts completion callbacks onto the UI thread
Using CSLA 4: Creating Business Objects Page 103
Rev 1.1
The Csla.Threading namespace includes an enhanced BackgroundWorker component that
handles some threading issues specific to CSLA .NET and the data portal. You can use the
BackgroundWorker from System.ComponentModel or from Csla.Threading as you choose, but if you
need your background thread to have access to the current user identity or other context data from
Csla.ApplicationContext you should consider using the one from Csla.Threading.

Either way the rule code follows the same structure:


public class LongRunningRule : Csla.Rules.BusinessRule
{
public LongRunningRule()
{
IsAsync = true;
}

protected override void Execute(Csla.Rules.RuleContext context)


{
var bw = new Csla.Threading.BackgroundWorker();
bw.DoWork += (o, e) =>
{
// implement long-running task here
// on background thread
e.Result = "some result value";
};
bw.RunWorkerCompleted += (o, e) =>
{
var result = e.Result;
// process result here on UI thread
context.Complete();
};
bw.RunWorkerAsync();
}
}

As with any rule, you can use the InputProperties list and InputPropertyValues dictionary to
safely provide copies of business object property values to the Execute method and code running
on the background thread. The code in the rule should use the AddOutValue method to return any
output values, or the various validation methods on the RuleContext object to return validation
results. Those methods can be called on the background or UI thread.
If you use AddOutValue to return an output value for any property other than the primary
property, you must remember to add those properties to the AffectedProperties list in the rule’s
constructor.
The Complete method of RuleContext must be called on the UI thread, which means it is called
in the RunWorkerCompleted event handler.

Creating a Dynamic Rule


It is also possible to create a rule that dynamically determines, at runtime, whether to be
synchronous or asynchronous as the rule is constructed. In the rule’s constructor you can apply
logic to decide whether to set the IsAsync property to true or false. You can then use that value
in your Execute method to execute the right code. Here’s the LongRunningRule example as a
dynamic rule:
public class LongRunningRule : Csla.Rules.BusinessRule
{
public LongRunningRule()
{

Using CSLA 4: Creating Business Objects Page 104


Rev 1.1
// decide whether to be async or not
IsAsync = true;
}

protected override void Execute(Csla.Rules.RuleContext context)


{
if (this.IsAsync)
{
var bw = new Csla.Threading.BackgroundWorker();
bw.DoWork += (o, e) =>
{
RuleImplementation(e);
};
bw.RunWorkerCompleted += (o, e) =>
{
ProcessResult(e.Result);
context.Complete();
};
bw.RunWorkerAsync();
}
else
{
var e = new System.ComponentModel.DoWorkEventArgs(null);
RuleImplementation(e);
ProcessResult(e.Result);
}
}

private void RuleImplementation(System.ComponentModel.DoWorkEventArgs e)


{
// implement rule here
e.Result = "some result value";
}

private void ProcessResult(object result)


{
// process result here on UI thread
}
}

I’ve pulled the rule implementation and the processing of results out into separate private
methods, and then those methods are invoked through a BackgroundWorker or directly, depending
on the value of the IsAsync property.
This all depends on the constructor containing some code (not shown) that determines whether
this particular instance of the rule should be synchronous or asynchronous.
Asynchronous rules complicate ASP.NET code (Web Forms, MVC, or services). You might use this
technique to implement rules that are asynchronous on a smart client, but synchronous when
running on the server. In that case, the constructor would look like this:
public LongRunningRule()
{
#if SILVERLIGHT
IsAsync = true;
#else
if (HttpContext.Current != null)
IsAsync = false;
else
IsAsync = true;
#endif
}

Using CSLA 4: Creating Business Objects Page 105


Rev 1.1
If HttpContext.Current contains a value, the code is running in ASP.NET. With this
implementation when the code is running on a server the rule will run synchronously, otherwise it
will run asynchronously.

Synchronous Execute in an Asynchronous Rule


Another way to approach the scenario where a rule should be synchronous or asynchronous
depending on context; is to build an asynchronous rule, and then decide whether to run
synchronously or asynchronously in the Execute method.
The one drawback to this approach is that CSLA .NET will always treat the rule as async, because
the IsAsync property will always be true. The Execute method itself can run synchronously if that
makes more sense, and that can be more efficient if you know at runtime that the “background
task” will take a very short amount of time to run.
Here’s the same example rule, but with the decision to be synchronous or asynchronous being
made in the Execute method instead of the rule’s constructor:
public class LongRunningRule : Csla.Rules.BusinessRule
{
public LongRunningRule()
{
IsAsync = true;
}

protected override void Execute(Csla.Rules.RuleContext context)


{
// decide whether to be async or not
bool runAsync = ???;
if (runAsync)
{
var bw = new Csla.Threading.BackgroundWorker();
bw.DoWork += (o, e) =>
{
RuleImplementation(e);
};
bw.RunWorkerCompleted += (o, e) =>
{
ProcessResult(e.Result);
context.Complete();
};
bw.RunWorkerAsync();
}
else
{
var e = new System.ComponentModel.DoWorkEventArgs(null);
RuleImplementation(e);
ProcessResult(e.Result);
context.Complete();
}
}

private void RuleImplementation(System.ComponentModel.DoWorkEventArgs e)


{
// implement rule here
e.Result = "some result value";
}

private void ProcessResult(object result)


{
// process result here on UI thread
}
}
Using CSLA 4: Creating Business Objects Page 106
Rev 1.1
There are two areas of difference from the previous implementation.
First, notice that the constructor always sets IsAsync to true, and that the first thing the
Execute method does is determine whether the rule should run asynchronously or not. How you
make that decision is up to your specific business requirements and the type of algorithm you are
implementing, so I’ve left a “???” placeholder in the example code.
Second, notice that the synchronous implementation now calls the Complete method on the
RuleContext object. This is necessary because CSLA .NET will always treat this rule as being
asynchronous because IsAsync is always true. All asynchronous rules (even if they don’t run
anything on a background thread) must call Complete when they are done, or CSLA .NET won’t
know that the rule has completed.
The conclusion you should draw from this is that an “asynchronous rule” is only potentially
asynchronous. If IsAsync is true, CSLA .NET will treat the rule as an asynchronous rule, but you can
decide whether to execute code on a background thread or not as you choose. Remember that if
IsAsync is true, you must call the Complete method on the RuleContext object to tell CSLA .NET
when the rule is done running.

Directly Accessing the Target Property


It is possible for an asynchronous rule to explicitly indicate that it needs access to the business
object instance by setting the rule’s ProvideTargetWhenAsync property to true in the rule’s
constructor.
public BusinessRuleClass(IPropertyInfo primaryProperty)
: base(primaryProperty)
{
ProvideTargetWhenAsync = true;
IsAsync = true;
}

When you set this property your rule implementation will be provided with a reference to the
business object. It is up to you to ensure that no code running on a background thread interacts
with the object or its properties. If you violate this restriction you may introduce bugs that are very
difficult to find, troubleshoot, or resolve.

Setting ProvideTargetWhenAsync to true is dangerous, and should only be done if


you understand the full ramifications of your decision.

Here’s the ProjectExists rule using the Target value:


public class ProjectExists : Csla.Rules.BusinessRule
{
public ProjectExists(Csla.Core.IPropertyInfo primaryProperty)
: base(primaryProperty)
{
IsAsync = true;
ProvideTargetWhenAsync = true;
}

protected override void Execute(Csla.Rules.RuleContext context)


{
var target = (Project)context.Target;
var id = (Guid)ReadProperty(target, Project.IdProperty);
Project.Exists(id, (result) =>

Using CSLA 4: Creating Business Objects Page 107


Rev 1.1
{
if (result)
context.AddWarningResult("Project already exists");
context.Complete();
});
}
}

The reason this is acceptable, is that I’m only using the Target value on the UI thread. I don’t use
the Target value in the callback lambda code, which might be running on a background thread
(though when using the data portal even that code does run on the UI thread).
You should implement most rules as synchronous rules, because they are generally simpler and
more efficient. When you need to make asynchronous calls to services or through the data portal,
or if you have a rule that implements a long-running algorithm that can run on a background thread
you will implement asynchronous rules.

Implementing Business Rules


Business rules are rules that encapsulate algorithmic processing, calculations, or simple changes to
property values. If you need a rule that changes the value of one or more properties of your object
then you are looking for a business rule.
I’ll walk through a simple example of a rule first, and then go through the various
implementation options in detail.
Business rules are implemented as a class, and they typically subclass the BusinessRule class
from the Csla.Rules namespace. For example:
public class ToUpper : Csla.Rules.BusinessRule
{
public ToUpper(Csla.Core.IPropertyInfo primaryProperty)
: base(primaryProperty)
{
InputProperties = new List<Csla.Core.IPropertyInfo> { PrimaryProperty };
}

protected override void Execute(Csla.Rules.RuleContext context)


{
var input = context.InputPropertyValues[PrimaryProperty].ToString();
if (!string.IsNullOrEmpty(input))
context.AddOutValue(PrimaryProperty, input.ToUpper());
}
}

This simple rule will uppercase any string property value.


The rule is a subclass of the BusinessRule class. The BusinessRule class implements the
IBusinessRule interface from the Csla.Rules namespace, and all rules must implement this
interface. The BusinessRule class provides some convenient behaviors common to most rules, and
so is usually simpler than implementing the IBusinessRule interface manually.
The rule also has a constructor which requires that a primaryProperty parameter be provided.
Some rules can be associated with business types, but most will require a primary property. This
constructor ensures that this rule is associated with a specific property. Notice that the
primaryProperty parameter is of type IPropertyInfo from the Csla.Core namespace. This
interface is the base type for all property info metadata fields, and is the correct type to use any
time you need a property info metadata field.
Using CSLA 4: Creating Business Objects Page 108
Rev 1.1
Within the constructor, the code uses the InputProperties property from the BusinessRule
base class. This is a protected property that contains a list of the property values that should be
copied out of the business object and made available to the rule when it is executed. The values of
any properties you put into this list will be available to the rule every time it runs.
The core of the rule is the Execute method. The BusinessRule base class already defines this
method, so the ToUpper rule overrides the method to implement the specific rule behavior.
protected override void Execute(Csla.Rules.RuleContext context)
{
var input = context.InputPropertyValues[PrimaryProperty].ToString();
if (!string.IsNullOrEmpty(input))
context.AddOutValue(PrimaryProperty, input.ToUpper());
}

For this simple rule, the Execute method gets the input value from the InputPropertyValues
dictionary in the context parameter. This value is available because the rule’s constructor added
the primary property to the InputProperties list as the rule was created.
If the input value contains a string value, the AddOutValue method is used to provide an output
value for the primary property. The property value will be set to this output value after the rule
completes. Notice that the output value is the uppercased input value.
The result is a rule that takes a string property value as input and sets that property to the
same string, but uppercased.

Using the Target Property


A variation on the implementation of the ToUpper rule is to use the Target property of the
RuleContext to directly interact with the business object. This will tightly couple the rule to the
business type, but may be appropriate in scenarios where a rule is being implementing for only one
specific type of business object.
The rule would look like this:
public class ToUpper : Csla.Rules.BusinessRule
{
protected override void Execute(Csla.Rules.RuleContext context)
{
var target = (ProductEdit)context.Target;
var name = (string)ReadProperty(target, ProductEdit.NameProperty);
LoadProperty(target, ProductEdit.NameProperty, name.ToUpper());
}
}

Notice how the Target property is cast to a specific business type, and then the ReadPropery
method from the BusinessRule base class is used to read the property value without triggering
authorization rules. Similarly, the LoadProperty method is used to update the property value.
While this implementation is somewhat more direct than the previous examples, you can easily
see how the code in the Execute method is tightly coupled to the ProductEdit business type, so
this rule isn’t generally useful for other business types.

Using CSLA 4: Creating Business Objects Page 109


Rev 1.1
Interacting with the Entire Object Graph
One direct benefit to using the Target property of the context object is that you can interact with
the entire business object, not just the property values provided through the InputPropertyValues
dictionary of the RuleContext object.
If your rule needs to interact with the business object’s parent, children, or other objects in the
object graph you will be able to access those other objects through the Target property. Here’s an
example of a rule that gets the reference to the business object’s parent object:
public class AddParentQuantity : Csla.Rules.BusinessRule
{
protected override void Execute(Csla.Rules.RuleContext context)
{
var target = (ProductLocation)context.Target;
var parent = (ProductEdit)target.Parent;
var quantity = (double)ReadProperty(parent, ProductEdit.QuantityProperty);
LoadProperty(parent, ProductEdit.QuantityProperty, quantity + 1);
}
}

Because this code has direct access to the Target property, it can use the business object’s
Parent property to access its parent. Given access to the parent object, that object’s properties can
be read and loaded with values as shown in the example.
You can use the same concept to access child objects or any other objects in the object graph.
At this point, you should understand how to create business rules that get and set properties of
the business object or other objects in the object graph.

Implementing Validation Rules


Validation rules are rules that return an error, warning, information, or success result value based
on the implementation of the rule. Validation rules don’t change the values of properties of the
business object or other objects in the object graph.
You can implement validation rules as classes, very much like the business rules I’ve discussed
earlier in this chapter. Alternatively, you can implement validation rules as DataAnnotations
attributes that subclass the ValidationAttribute base class.

Broken Rules Collection


Editable objects maintain a list of broken validation rules for the object and the object’s properties.
Rules are added and removed from this list based on the results returned as each validation rule is
invoked.
The list of broken rules is maintained in a BrokenRulesCollection and the BusinessBase base
class has a public BrokenRulesCollection property you can use within the object or in your UI code
to access the list of broken rules. You can use LINQ queries to easily sort and filter the information.
For example, this query returns a list of all broken rules for the City property:
var rulesForProperty = from r in this.BrokenRulesCollection
where r.Property == CityProperty.Name
select r;

Using CSLA 4: Creating Business Objects Page 110


Rev 1.1
As I discussed in Chapter 1, the IsSelfValid property is based on this broken rules collection. If
the collection is empty, the object has no broken rules and so IsSelfValid returns true. Otherwise
it returns false.
You can’t directly add or remove items from the broken rules collection. Instead, you implement
validation rules and as they execute their results are added and removed from the collection.

Validation Rule Classes


Standard validation rules are implemented following the same structure and concepts as with
business rules. Nearly everything I’ve discussed so far in this chapter applies to validation rules as
well as business rules. Again, the only real difference is that validation rules return error, warning,
information, or success results instead of changing property values.
Here’s a simple validation rule implementation:
public class ValidPrefix : Csla.Rules.BusinessRule
{
public string Prefix { get; private set; }

public ValidPrefix(Csla.Core.IPropertyInfo primaryProperty, string prefix)


: base(primaryProperty)
{
InputProperties = new List<Csla.Core.IPropertyInfo> { PrimaryProperty };
Prefix = prefix;
RuleUri.AddQueryParameter("prefix", prefix);
}

protected override void Execute(Csla.Rules.RuleContext context)


{
var text = (string)context.InputPropertyValues[PrimaryProperty];
if (!string.IsNullOrEmpty(text) && !text.StartsWith(Prefix))
context.AddErrorResult(
string.Format("Value must start with {0}", Prefix));
}
}

This rule has a constructor that requires a primary property, and a parameter with the prefix
required for the property value. As with business rules, notice that the parameter value is added to
the RuleUri to help ensure this rule has a unique RuleName value.

Unique RuleName values are more important for validation rules than business rules,
because this is the name used to identify the rule within the broken rules collection.

The Execute method checks to see if the input value starts with the prefix. If it doesn’t, the
AddErrorResult method of the RuleContext object is used to add an error result to the output of
the rule.
Once the rule completes, any output results, such as this error, are added to the broken rules
collection. If the rule doesn’t return any result, it is assumed that the rule was successful and any
existing broken rules entries for this rule are removed from the broken rules list.

Rule Severity
Rules can return results with different severity:

 Error
Using CSLA 4: Creating Business Objects Page 111
Rev 1.1
 Warning
 Information
 Success

Error severity indicates that the broken rule should prevent the object from being saved. Broken
rules of this severity appear as validation rule violations in all data binding technologies, and
seamlessly integrate into any standard .NET or Silverlight validation schemes. For example, Error
severity rules are automatically displayed by the Windows Forms ErrorProvider control, the
ASP.NET MVC validation behaviors, and the WPF and Silverlight validation mechanisms.
This automatic display of validation errors is only true for Error severity rules. Microsoft’s data
binding technologies have no concept of validation severity, and so they won’t automatically display
information for any other severities.
CSLA .NET includes UI helper components for several of the UI technologies to make it easy to
display Warning and Information severity rules to the user. For example, the PropertyInfo control
for Silverlight, WPF, and WP7 and the PropertyStatus control for Silverlight and WPF make it easy
to display rules of any severity to the user.
Warning severity indicates that the broken rule is merely a warning. The business object can still
be saved, but the user should be notified that there is some concern about the property value or
the state of the object.
Information severity indicates that the broken rule is purely an informational message. The
business object can be saved and the user should be shown the message.
Success severity is special, in that all it does is indicate success with no message for display to the
user. Earlier I mentioned that the default is success, so in most cases there’s no need to explicitly
indicate success by calling AddSuccessResult. This is one example of our discussion about short-
circuiting and rule priorities earlier in this chapter.
It is possible for a rule to explicitly indicate that no subsequent rules should execute. A rule can
explicitly trigger short-circuiting. All the RuleContext methods that add validation rules for error,
warning, information, and success have overloads that allow you to specify a Boolean value
indicating that rule processing should be short-circuited.
In the case that a rule is silently successful, but still needs to cause short-circuiting, your rule will
call AddSuccessResult with a parameter of true to prevent any subsequent rules from executing.

DataAnnotations Attributes
While most validation rules will be implemented as subclasses of the BusinessRule base class, you
can also implement validation rules as validation attributes by subclassing the
ValidationAttribute base class in the System.ComponentModel.DataAnnotations namespace.
Rules implemented this way aren’t as powerful or flexible as CSLA .NET rules, because they can’t
specify priorities, trigger short-circuiting, run asynchronously, or return anything but Error severity
results. On the other hand, applying validation rules as an attribute on a business class property is
very convenient and results in readable code. For simple, synchronous validation rules I’ll often
implement the rules as validation attributes.
Using CSLA 4: Creating Business Objects Page 112
Rev 1.1
Remember that any validation attributes are treated as normal validation rules by CSLA .NET, so
they run along with all other priority 0 rules when CheckRules is called. The primary difference is
one of implementation. Here’s an example of a simple rule implemented as a validation attribute:
[AttributeUsage(AttributeTargets.Property)]
public class ValidPrefix : System.ComponentModel.DataAnnotations.ValidationAttribute
{
public string Prefix { get; private set; }

public ValidPrefix(string prefix)


{
Prefix = prefix;
}

protected override System.ComponentModel.DataAnnotations.ValidationResult IsValid(


object value, System.ComponentModel.DataAnnotations.ValidationContext validationContext)
{
var text = (string)value;
if (!string.IsNullOrEmpty(text) && !text.StartsWith(Prefix))
return new System.ComponentModel.DataAnnotations.ValidationResult(
string.Format("Value must start with {0}", Prefix));
else
return null;
}
}

This rule is implemented as a .NET attribute, and it inherits from ValidationAttribute so it can
participate in the normal DataAnnotations behaviors as supported by ASP.NET MVC and the
Silverlight DataForm control.
The rule defines a constructor to require the prefix it will require for the property value. It is
applied to a property in a business class like this:
public static readonly PropertyInfo<string> MyNameProperty = RegisterProperty<string>(c => c.Name);
[ValidPrefix("SOP")]
public string Name
{
get { return GetProperty(MyTextProperty); }
set { SetProperty(MyTextProperty, value); }
}

The ValidationAttribute base class defines a protected method named IsValid that the rule
overrides to provide its implementation. This IsValid method takes two parameters, the property
value to be validated and a ValidationContext parameter with extra information.
For this simple rule the value parameter is checked to see if it starts with the required prefix. If
not, a ValidationResult object containing the error message is returned. To indicate success,
return a null value.
You should be aware that the ValidationContext parameter includes an ObjectInstance
property, which is similar to the Target property of the RuleContext parameter in standard CSLA
.NET rules. You can use this ObjectInstance property to access other properties of the business
object, though doing so will couple your rule to the business type and will reduce the ability to
reuse your rule.

Accessing Rule Information and Results


You may need to get a list of the rules associated with a business type, or the results of any
validation rules associated with a business object or its properties. CSLA .NET provides access to this
Using CSLA 4: Creating Business Objects Page 113
Rev 1.1
information through its own types and properties, and through data binding interfaces defined by
the .NET Framework and Silverlight runtime.

Get a List of Rules for a Type


You can get a list of the business rules associated with an editable business object and all of its
properties by using the GetRuleDescriptions method on the business object’s BusinessRules
property. The results of this method can be accessed using the RuleUri type from the Csla.Rules
namespace.

GetRuleDescriptions Method
The GetRuleDescriptions method on the BusinessRules property returns an array of string
values. Each value is in URI format, with a rule:// URI prefix. The method is called within an
editable business class like this:
var rules = BusinessRules.GetRuleDescriptions();

The result is a string array containing rule:// URI values. Each URI contains several fields of
information, including:

 Rule type name


 Primary property name
 Dictionary of rule arguments

A complete list of elements can be found in Table 22.


As I discussed earlier, the rule type name can be extremely long, and may be divided into
multiple parts of a “virtual path”. The URI specification has limits on the length of its elements, and
CSLA .NET will automatically break the rule’s type name into elements that fit within those limits.
The dictionary of rule arguments uses the name of each argument as a key, and provides the
value associated with that argument name. It is the responsibility of the rule to add any custom
argument values to the rule’s URI description. For example, here’s a rule that requires a max
argument value:
public class MyRule : Csla.Rules.BusinessRule
{
private int _max;

public MyRule(Csla.Core.IPropertyInfo primaryProperty, int max)


: base(primaryProperty)
{
_max = max;
InputProperties = new List<Csla.Core.IPropertyInfo> { PrimaryProperty };
RuleUri.AddQueryParameter("max", _max.ToString());
}

protected override void Execute(Csla.Rules.RuleContext context)


{
object input = context.InputPropertyValues[PrimaryProperty];
// implement rule here
}
}

Using CSLA 4: Creating Business Objects Page 114


Rev 1.1
Notice the call to the AddQueryParameter method of the RuleUri property provided by the
BusinessRule base calss. This method is used in the rule’s constructor to add the custom argument
value to the rule description.

It is very important that all argument values be added to the rule description. The
rule description must be unique, and without the argument values, the rule
description may not be unique.

The RuleUri type from the Csla.Rules namespace can be used to parse each of the elements of
the string array returned as a result of the GetRuleDescriptions method.

RuleUri Type
The RuleUri type is similar to the Uri type provided by the .NET Framework. It accepts a rule://
URI, and parses that value so you can easily access the various parts of the URI.
For example, the following code gets the list of rules for an object, and filters the values to get
the list of rules for the Name property:
var rules = BusinessRules.GetRuleDescriptions();
var ruleUriList = rules.Select(r => new RuleUri(r));
var nameRules = ruleUriList.Where(r => r.PropertyName == NameProperty.Name);

This code uses a LINQ expression to convert the string array into a list of RuleUri objects. It
then uses another LINQ expression to filter the list of RuleUri objects by the PropertyName
property.

Get Rule Results from an Object


The results of validation rules are automatically exposed to all .NET UI technologies through
standard data binding interfaces defined by the .NET Framework or Silverlight runtime. In many
cases you can simply rely on the standard data binding behaviors to allow your application to access
the results of an object’s validation rules.
I’ll discuss the data binding interfaces that apply to WPF, Silverlight, ASP.NET MVC, and WP7 in
subsequent books in the Using CSLA 4 ebook series. The interfaces include:

 IDataErrorInfo
 INotifyDataErrorInfo

It is also possible to manually access the validation rule results by accessing the list of “broken
rules” associated with an editable business object.
As validation rules are executed, their results are maintained in a list of broken validation rules.
Every editable business object maintains a list of the broken rules associated with the object and its
properties.

BrokenRulesCollection Property
The BusinessBase base class in the Csla namespace exposes a public property named
BrokenRulesCollection. This property provides access to a read-only snapshot of the complete
broken rules collection for the business object.
Using CSLA 4: Creating Business Objects Page 115
Rev 1.1
The result is a BrokenRulesCollection object, which is a collection of BrokenRule objects. The
BrokenRulesCollection object is a subclass of the ObservableCollection<T> type defined by the
.NET Framework. This means that the collection is bindable in all UI technologies with the exception
of Windows Forms. If you want to display the list of broken rules to the user, you may be able to
bind this collection directly to your UI.
You can also use LINQ queries to interact with the collection. For example, this code filters the
list of broken rules by property name:
var nameRules =
customer.BrokenRulesCollection.Where(r => r.Property == CustomerEdit.NameProperty.Name);

This code assumes the customer field references a CustomerEdit business object. It accesses the
BrokenRulesCollection property and applies a LINQ Where clause to filter the results to get the
broken rules for the Name property.
The BrokenRule type exposes the properties listed in Table 23.

Property Description
Property Name of the property to which the rule is attached; may be null for a per-object
rule
RuleName Name of the rule as a rule:// URI
Description Friendly description of the rule, for display to the user
Severity RuleSeverity value of the rule (Error, Warning, or Information)

Table 23. Properties available on a BrokenRule object


You can use the RuleUri type from the Csla.Rules namespace to parse the RuleName property.

GetBrokenRules Method
The BusinessRules object for a business object exposes a GetBrokenRules method. This method
returns the same BrokenRulesCollection object as the BrokenRulesCollection property of the
BusinessBase class.
In fact, the implementation of the BrokenRulesCollection property in the BusinessBase class
uses the GetBrokenRules method of the BusinessRules object to get its result.

GetAllBrokenRules Method
The BusinessRules type also exposes a GetAllBrokenRules method. This is a static method that
accepts a business object as a parameter. The purpose of this method is to combine the broken
rules collections for all business objects in an entire object graph into a single result.
For example, you might have an object graph with an OrderEdit editable root. Assuming that
OrderEdit object contains a collection of LineItemEdit objects, you might want to get a
consolidated list of all broken rules for the order and its line items. This can be done using the
GetAllBrokenRules method:
var allRules = BusinessRules.GetAllBrokenRules(order);

Using CSLA 4: Creating Business Objects Page 116


Rev 1.1
The GetAllBrokenRules method returns a BrokenRulesTree object. This is a list of
BrokenRulesNode objects. Table 24 lists the properties implemented by the BrokenRulesNode type.

Property Description
Object Reference to the business object associated with this node
BrokenRules Reference to the BrokenRulesCollection for the business object associated with
this node
Parent Reference to the parent BrokenRulesNode object; null if the current object is the
root, otherwise the parent node corresponds to the parent business object of the
current business object
Node Node key value (for internal use)

Table 24. Properties available on a BrokenRulesNode object


Each business object in the object graph gets one entry in the BrokenRulesTree list, so each
BrokenRulesNode object corresponds to one business object in the object graph. You can use LINQ
queries to interact with the results. For example, the following code returns a list of business
objects that have Error severity broken rules:
var allRules = BusinessRules.GetAllBrokenRules(order);
var errors = from r in allRules
where r.BrokenRules.Any(x => x.Severity == RuleSeverity.Error)
select r.Object;

The GetAllBrokenRules method is typically used to get a list of all broken rules for an object
graph for the purpose of populating some display in the UI to show the user a consolidated view of
all broken rules associated with their current task.
At this point, you should understand how to create business and validation rules, how to
associate them with properties or business types, and how they are executed automatically or
manually as your business objects are used by the application.
You’ll see more examples of these concepts in subsequent ebooks in the series. In those ebooks
I’ll also demonstrate how validation rules integrate with the various data binding technologies and
CSLA .NET helper controls for each type of UI.

Authorization Rules
Authorization rules are slightly different from business and validation rules, though they are as
similar as possible. As I discuss how to use and implement authorization rules I will assume that you
already understand how business and validation rules are used and implemented.
Authorization is the process of determining whether the current user is allowed to perform
various actions. CSLA .NET allows you to apply authorization rules to the following actions:

 Read a property
 Set a property
 Execute a method
 Create a business object
Using CSLA 4: Creating Business Objects Page 117
Rev 1.1
 Retrieve a business object
 Edit (save) a business object
 Delete a business object

Some of these rules apply to members of a specific business object instance, and so are per-
property or per-method rules, while other rules apply to the type of object rather than any specific
instance.
For example, the rules that control whether the current user can create or retrieve a
CustomerEdit object must apply to the business type because the rules are applied before any
object instance exists. On the other hand, a rule controlling whether the current user can read a
property is applied as the user tries to read a property from a specific object instance and so that
rule runs within the context of that object instance.
The per-property and per-method actions are:

 Read a property
 Set a property
 Execute a method

The per-type actions are:

 Create a business object


 Retrieve a business object
 Edit (save) a business object
 Delete a business object

The most important thing to remember is that authorization rules are business logic, not
security. Authorization rules control whether the current user is allowed to perform certain actions
based on the business rules surrounding those actions.
Sometimes this decision is as simple as determining whether the user is or isn’t in a certain
group or role. Other times the decision must take into account the state of the business object, the
state of the application as a whole, or other information from the user’s profile or claims.
CSLA .NET provides two pre-built rules that work with the standard .NET role-based
authorization model. These rules are IsInRole and IsNotInRole and are found in the
Csla.Rules.CommonRules namespace. You may find these rules to be sufficient for your
authorization requirements, or you may need to implement your own authorization rules to meet
your application requriements.
For example, your application might not use roles at all, but instead might use other information
from the user’s profile to determine what actions the user can and can’t perform. I’ll discuss
authentication and loading user identity information in the Using CSLA 4: Security ebook, but in
most cases you can assume that your authorization rules will have access to various user profile or
claims information as necessary.

Using CSLA 4: Creating Business Objects Page 118


Rev 1.1
One authorization rule can be associated with any action. So you can associate exactly one
authorization rule with the read the City property action, and one rule with the write the City
property action.
The restriction to one rule per action is to help ensure that authorization doesn’t become a
performance issue. Due to the way data binding works in most smart client UI technologies, per-
property authorization rules are run frequently, and I chose to restrict the implemention to one rule
per action to minimize any performance impact.
Authorization rules are permissive by default. This means that if you don’t specify a rule for an
action, all users are authorized to perform that action. For example, if you don’t explicitly indicate
which users can and can’t read a property, then all users can read that property.
I’ll start by showing how rules are associated with properties, methods, and business types, then
I’ll discuss how authorization rules are executed, and finally I’ll walk through the process of creating
your own custom authorization rules.

Associating Rules with Properties and Types


Per-property and per-method authorization rules are associated with your business type’s
properties and methods by overriding AddBusinessRules, just like business and validation rules.
Per-type authorization rules are associated with the business type by implementing a static method
named AddObjectAuthorizationRules in your business class.

Using AddBusinessRules
Per-property and per-method authorization rules are associated with the properties and methods
of your business type by overriding the AddBusinessRules method and calling the AddRule method
of the BusinessRules object. This process is essentially the same as associating business and
validation rules with your properties.
To associate rules to properties and methods you’ll write code like this in your business class:
protected override void AddBusinessRules()
{
base.AddBusinessRules();
BusinessRules.AddRule(new Csla.Rules.CommonRules.IsInRole(
Csla.Rules.AuthorizationActions.ReadProperty, CityProperty, "User", "Supervisor"));
BusinessRules.AddRule(new Csla.Rules.CommonRules.IsInRole(
Csla.Rules.AuthorizationActions.WriteProperty, CityProperty, "Supervisor"));
BusinessRules.AddRule(new Csla.Rules.CommonRules.IsInRole(
Csla.Rules.AuthorizationActions.ExecuteMethod, TestMethod, "Supervisor"));
}

In this example, I’m using the IsInRole rule to indicate that the User and Supervisor roles are
allowed to read the City property, but only the Supervisor role is allowed to write to that property.
Similarly, only the Supervisor role is allowed to execute the Test method.
Your AddBusinessRules override will typically contain a mix of business, validation, and
authorization rule associations. I normally try to either organize the AddRule calls by property or by
rule type, you should determine an organizational approach that works for you and standardize on
that coding pattern.

Using CSLA 4: Creating Business Objects Page 119


Rev 1.1
Using AddObjectAuthorizationRules
Per-type authorization rules are often executed before any instance of the business type has been
created. For example, the very first time a user attempts to create a CustomerEdit object, the rule
controlling whether they are allowed to create that object is run – before the object is created.
This means the per-type authorization rules for a business type must be defined before the
create or retrieve actions can be authorized. The AddBusinessRules method executes when the
first instance of a business type has been created. Unfortunatly, that method is run too late to
define per-type rules. The solution is that CSLA .NET looks for a static method named
AddObjectAuthorizationRules in your business class and this method is invoked before the
business type is used.
In pure .NET code, this method can be private in scope, but due to the restrictions on reflection
in Silverlight and WP7, the method must be public in those environments. I generally make the
method public in all cases for consistency.

You should never call this method explicitly. CSLA .NET will call this method
automatically to initialize your authorization rules one time during the life of each
AppDomain.

To associate rules to your business type you’ll write code like this in your business class:
public static void AddObjectAuthorizationRules()
{
Csla.Rules.BusinessRules.AddRule(typeof(ProductEdit),
new Csla.Rules.CommonRules.IsInRole(
Csla.Rules.AuthorizationActions.CreateObject, "Supervisor"));
Csla.Rules.BusinessRules.AddRule(typeof(ProductEdit),
new Csla.Rules.CommonRules.IsInRole(
Csla.Rules.AuthorizationActions.GetObject, "User", "Supervisor"));
Csla.Rules.BusinessRules.AddRule(typeof(ProductEdit),
new Csla.Rules.CommonRules.IsInRole(
Csla.Rules.AuthorizationActions.EditObject, "Supervisor"));
Csla.Rules.BusinessRules.AddRule(typeof(ProductEdit),
new Csla.Rules.CommonRules.IsInRole(
Csla.Rules.AuthorizationActions.DeleteObject, "Supervisor"));
}

I’m using the IsInRole rule, and associating it with the create, get, edit, and delete actions for
the ProductEdit business type. In this example, the Supervisor role is allowed to perform all four
actions, but the User role is only allowed to get (retrieve) objects of type ProductEdit.
Because AddObjectAuthorizationRules is a static method, the AddRule method I’m calling is a
static method on the BusinessRules type in the Csla.Rules namespace.

These per-type authorization rules are enforced by the data portal, so it is important that users
avoid the use of the new keyword to create business objects, and instead invoke factory methods
(which use the data portal) to create or retrieve instances of business objects. If you do use the new
keyword to create instances of your business objects, you shouldn’t be surprised when the
authorization rules aren’t applied.

Using CSLA 4: Creating Business Objects Page 120


Rev 1.1
Rule Sets
I discussed how rule sets are used for business and validation rules. They work the same way for
authorization rules. Within your AddBusinessRules method you’ll use code like this:
protected override void AddBusinessRules()
{
base.AddBusinessRules();

// associate rules for default rule set


BusinessRules.AddRule(new Csla.Rules.CommonRules.IsInRole(
Csla.Rules.AuthorizationActions.ReadProperty, CityProperty, "User", "Supervisor"));

// associate rules for rule set A


BusinessRules.RuleSet = "RuleSetA";
BusinessRules.AddRule(new Csla.Rules.CommonRules.IsInRole(
Csla.Rules.AuthorizationActions.ReadProperty, CityProperty, "NormalUser", "SuperUser"));

// use default rule set


BusinessRules.RuleSet = "default";
}

In this example, the default rule set uses the User and Supervisor roles, while RuleSetA has
different roles defined for its users; and so the roles supplied to the rule are different.
Similar code is used in the AddObjectAuthorizationRules method:
public static void AddObjectAuthorizationRules()
{
// associate rules for default rule set
Csla.Rules.BusinessRules.AddRule(typeof(EditableProperties),
new Csla.Rules.CommonRules.IsInRole(
Csla.Rules.AuthorizationActions.CreateObject, "Supervisor"));

// associate rules for rule set A


Csla.ApplicationContext.RuleSet = "RuleSetA";
Csla.Rules.BusinessRules.AddRule(typeof(EditableProperties),
new Csla.Rules.CommonRules.IsInRole(
Csla.Rules.AuthorizationActions.CreateObject, "SuperUser"));

// use default rule set


Csla.ApplicationContext.RuleSet = "default";
}

Notice that in this case, the current rule set is controlled by the RuleSet property on the
Csla.ApplicationContext object. This property controls which rule set is used for per-type rules
for the current user application-wide. For per-type rules, you don’t control the rule set for each
business object or type; you control it for the entire application by changing this global property
value.
The ApplicationContext object is user-specific, so even in a multi-user server scenario the
RuleSet property only affects the current user. That way, each user can be using a different rule
set.

Executing Rules
Like business and validation rules, authorization rules are normally executed automatically.
The GetProperty, GetPropertyConvert, SetProperty, and SetPropertyConvert methods
automatically check authorization rules before doing any other work. The data portal automatically
checks authorization rules before any create, fetch, save, or delete operations.
Using CSLA 4: Creating Business Objects Page 121
Rev 1.1
The one exception is the ExecuteMethod action, which you must explicitly invoke at the top of
any method you implement. I discussed this in Chapter 1, and here’s the code example from that
chapter:
public static readonly MethodInfo TestMethod = RegisterMethod(typeof(EditableProperties), "Test");
public void Test()
{
CanExecuteMethod(TestMethod);
// do some work here
}

The first line of code in the Test method is a call to CanExecuteMethod, which executes any
authorization rule associated with the Test method to find out if the user is authorized to perform
this action.

Manually Executing Rules


It is possible to explicitly check the authorization rules for all actions. In fact, the methods to
perform those checks are all publicly available so they can be used by code inside your business
class, but also by code in the UI.
A good UI developer will show the user visual cues to help indicate that the user isn’t authorized
to view or change a property value, or perform actions linked to UI controls like buttons. To do this,
the UI developer might disable or hide controls. The authorization rules are in the business objects,
and they shouldn’t be replicated in the UI code, but the UI code does need some way to determine
the results of those authorization rules.
The idea is that the authorization rules associated with the properties, methods, and business
types in your business layer should be available to any code in the interface control and business
layer. To make this possible, CSLA .NET defines public interfaces and methods that allow any code
to execute the authorization rules.

Per-Property and Per-Method Rules


The per-property and per-method rules can be executed through the IAuthorizeReadWrite
interface in the Csla.Security namespace. This interface is implemented by the BusinessBase and
ReadOnlyBase base classes, and so is available on all editable and read-only object stereotypes.
You can use the IAuthorizeReadWrite interface like this:
var iarw = (Csla.Security.IAuthorizeReadWrite)_product;
bool canExecute = iarw.CanExecuteMethod("Test");
bool canRead = iarw.CanReadProperty("Name");
bool canWrite = iarw.CanWriteProperty("Name");

Notice that this interface uses string literal values for the names of properties and methods.
This is because most UI code is driving off data binding information, and so won’t have access to the
static metadata fields describing each property or method.

The BusinessBase and ReadOnlyBase base classes also expose public methods you can use
directly. These methods have overloads that accept either an IPropertyInfo metadata field or a
string literal:
ProductEdit obj = _obj;
bool canExecute = obj.CanExecuteMethod(ProductEdit.TestMethod);

Using CSLA 4: Creating Business Objects Page 122


Rev 1.1
bool canRead = obj.CanReadProperty(ProductEdit.CityProperty);
bool canWrite = obj.CanWriteProperty(ProductEdit.CityProperty);

You can use the interface or the public methods as appropriate for your application needs.

Per-Type Rules
The per-type rules can be executed through the BusinessRules class in the Csla.Rules namespace.
This class exposes a set of HasPermission methods that are static and public, so any code in your
application can check the per-type rules.
You can use these static methods like this:
bool canCreate = Csla.Rules.BusinessRules.HasPermission(
Csla.Rules.AuthorizationActions.CreateObject, typeof(ProductEdit));
bool canGet = Csla.Rules.BusinessRules.HasPermission(
Csla.Rules.AuthorizationActions.GetObject, typeof(ProductEdit));
bool canEdit = Csla.Rules.BusinessRules.HasPermission(
Csla.Rules.AuthorizationActions.EditObject, typeof(ProductEdit));
bool canDelete = Csla.Rules.BusinessRules.HasPermission(
Csla.Rules.AuthorizationActions.DeleteObject, typeof(ProductEdit));

As you can see from the example code, you can use this technique to execute the per-type rules
for any of the four per-type actions on a business type.
You can also use an overload of these methods to specify the rule set to use when checking the
rule:
bool canCreate = Csla.Rules.BusinessRules.HasPermission(
Csla.Rules.AuthorizationActions.CreateObject, typeof(ProductEdit), "RuleSetA");

Finally, for the edit and delete actions you might have an object instance you can supply to the
rule:
bool canEdit = Csla.Rules.BusinessRules.HasPermission(
Csla.Rules.AuthorizationActions.EditObject, obj);

When I discuss how you can implement per-type authorization rules, you’ll see how this object
instance is made available to the rule’s code. Obviously, you’ll never have an object instance to
provide to a create or get action, but you’ll often have an instance for edit and delete actions.

Suppressing Rule Execution


Authorization rules are suppressed using the same techniques listed in Table 19, which I discussed
earlier in this chapter. To summarize, you can use one of the following techniques:

 BypassPropertyChecks property
 ICheckRules interface
 SuppressRuleChecking property

The scenarios where each technique should be used for authorization rules are the same as
those for business and validation rules. Please refer to Table 19 for more information.
At this point, you should understand how to associate authorization rules with properties,
methods, and business types; as well as how these rules are executed, and how you can suppress
rule execution. I’ll move on to discuss how to create custom authorization rules.
Using CSLA 4: Creating Business Objects Page 123
Rev 1.1
Implementing Authorization Rules
The role-based authorization supported by the CSLA .NET IsInRole and IsNotInRole rules is built
directly on the support for role-based authorization provided by the .NET framework. Many
applications can use this role-based model without the need for custom rules.
There are cases where simple role-based rules aren’t sufficient. For example:

 The state of the business object must be taken into account


 Other information about the user must be taken into account
 A claims-based authorization model is being used instead of a role-based model
 A permissions-based authorization model is being used instead of a role-based model

Remember that authorization rules are business rules, not security rules. So it is quite common
to need a custom rule to control whether the current user can read or write a property value based
on the state of other properties in the object. For example, you might have a property that can only
be changed if the object is new, so your custom rule needs to take the object’s IsNew property into
account as part of its behavior.

Structure of a Rule
Authorization rules follow a consistent structure. They must implement the IAuthorizationRule
interface from the Csla.Rules namespace, but they’ll usually subclass the AuthorizationRule class
to make the process simpler. Here’s the basic structure of a rule:
public class MyAuthorizationRule : Csla.Rules.AuthorizationRule
{
public string AllowedRole { get; private set; }

public MyAuthorizationRule(
Csla.Rules.AuthorizationActions action, Csla.Core.IMemberInfo element, string allowedRole)
: base(action, element)
{
AllowedRole = allowedRole;
}

protected override void Execute(Csla.Rules.AuthorizationContext context)


{
if (Csla.ApplicationContext.User.IsInRole(AllowedRole))
context.HasPermission = true;
else
context.HasPermission = false;
}
}

Authorization rules are implemented as a class, and they normally inherit from the
AuthorizationRule base class. They also must have a constructor, because every rule must at least
be associated with an action from the AuthorizationActions type, and most rules are also
associated with a property or method. The IMemberInfo interface from the Csla.Core namespace
allows this rule to be associated with either a property (IPropertyInfo) or a method
(IMethodInfo).
In this example, the rule also requires an allowedRole parameter; which is the one role that is
allowed to perform the action. That value is stored in an instance-level property or field of the
object.
Using CSLA 4: Creating Business Objects Page 124
Rev 1.1
The implementation of the rule itself goes in the Execute method; which is passed an
AuthorizationContext parameter containing information about the action, member, and business
object for which this rule is running. The AuthorizationContext is also used to return the results of
the rule through its HasPermission property.
This simple rule checks to see if the current user is in the correct role, and the HasPermission
property of the AuthorizationContext parameter is set accordingly.

AuthorizationContext Parameter
The AuthorizationContext parameter passed to the Execute method of the rule is at the heart of
the rule implementation. Table 25 lists the members of the AuthorizationContext type.

Member Description
Rule Provides a reference to the authorization rule
Target Provides a reference to the business object; this value will be
null if there is no object instance (such as for create and retrieve
actions)
TargetType Gets the type of the business object
HasPermission Set this to the result of the rule: true indicates the user should
be allowed to perform the action, false means the user doesn’t
have permission to perform the action

Table 25. Members defined by the AuthorizationContext type


At the very least, every authorization rule must set the HasPermission property of the
AuthorizationContext parameter to the result of the rule.

Rule implementations can also make use of the Target and TargetType properties to apply
behaviors that are specific to a business object or business type.
The TargetType value is always available, but it is important to recognize that the Target
property might be null. While per-property and per-method rules always have a business object to
populate the Target property, not all per-type actions will have a business object. For certain, you
know that the CreateObject and GetObject actions will not have a business object, because these
rules run before an object is created to determine whether the user is allowed to create or get the
object.

Any rule implementation that uses the Target property must check the value to see
if it is null before proceeding.

Here’s an example where I’m using the Target property in an Execute method:
protected override void Execute(Csla.Rules.AuthorizationContext context)
{
var target = context.Target as ProductEdit;
bool isNew = false;
if (target != null)
isNew = target.IsNew;
if (isNew && Csla.ApplicationContext.User.IsInRole(AllowedRole))
context.HasPermission = true;
Using CSLA 4: Creating Business Objects Page 125
Rev 1.1
else
context.HasPermission = false;
}

I cast the Target property to my business type, then I check to see if the value is null, and only
interact with it if it contains a valid reference.
You can combine the information from the AuthorizationContext parameter with the
properties available from the AuthorizationRule base class and the current user’s identity from
the User property of the Csla.ApplicationContext object to implement powerful and flexible
authorization rules.

IAuthorizationRule Interface
All authorization rules must implement the IAuthorizationRule interface from the Csla.Rules
namespace. Typically, rules will subclass the AuthorizationRule base class that already implements
this interface, but in some advanced scenarios you may choose to implement the interface directly.
The members of the interface are listed in Table 26.

Member Description
Action Gets the AuthorizationActions value specifying the action
this rule is authorizing
Element Gets the IMemberInfo metadata field for the property or
method with which this rule is associated; this value is null if the
rule is associated with a business type
CacheResult Gets a Boolean value indicating whether the result of this rule can
be cached by the calling code
Execute This is the method that is invoked when the rule is executed

Table 26. Members defined by the IAuthorizationRule interface


The Action and Element properties define the association for each rule. There can be exactly
one rule for each action/element pair. For example, there can be one rule for the ReadProperty
action of the Name property on a business type.
The CacheResult property indicates whether the result of the rule can be cached by the calling
code. Remember that most of the time rules are executed automatically by BusinessBase,
ReadOnlyBase, or other CSLA .NET base classes.

The BusinessBase and ReadOnlyBase classes implement caching of per-property and per-
method authorization results as a performance optimization. For role-based rules this is fine,
because the cache is automatically discarded any time the identity of the current user is changed.
But for some custom rules, especially those that are sensitive to the state of the business object,
the result must not be cached.
You’ve seen how the Execute method contains the implementation of the rule. The result of the
Execute method is provided through the HasPermission property of the AuthorizationRules
parameter.

Using CSLA 4: Creating Business Objects Page 126


Rev 1.1
AuthorizationRule Class
Most of the time, you will create authorization rules by subclassing the AuthorizationRule base
class. This class implements the IAuthorizationRule interface and provides some basic behaviors
that make it simpler to implement a rule.
The AuthorizationRule class maintains the Action and Element values required by the
IAuthorizationRule interface, and has constructors that require at least the Action value be
provided as the object is created. The Element value is optional, because per-type rules won’t
specify this value.
The base class also defines a CacheResult property, with a default value of true. You should
override the CacheResult property and return a value of false if your rule’s result shouldn’t be
cached.
It also defines the Execute method as an abstract virtual method, so your rule class must
override this method in its implementation.

Rule State
In my example rule class, I included an instance-level property:
public string AllowedRole { get; private set; }

The restrictions on instance-level properties and fields in authorization rules are the same as for
business and validation rules. Once the object has been initialized, you must never change the
values of any instance-level properties or fields.
Remember that each authorization rule instance is shared by all instances of the business type to
which the rule is associated. If you change the value of any instance-level properties or fields in an
authorization rule, you will instantly affect all the business objects to which that rule is associated.
This can lead to bugs that are very difficult to locate and fix.
Authorization rules are generally much simpler than business or validation rules. They return a
Boolean result indicating whether the current user is allowed to perform the specified action, so
they don’t have all the options and complexity of rule priorities, severities, or asynchronous
behaviors.
At this point, you should understand how to associate authorization rules with properties,
methods, and business types, as well as how the rules are executed, and how you can create your
own custom rules.

Using CSLA 4: Creating Business Objects Page 127


Rev 1.1
Conclusion
This book has provided you with the information necessary to use the CSLA .NET framework to
create the business domain objects that make up a business layer for your application. These
domain objects encapsulate behavior, and contain the state necessary to implement that behavior.
You have learned how to implement business rules, validation rules, and authorization rules, along
with public properties that provide access to select elements of the object’s state.
This is the second in a series of ebooks. Subsequent ebooks will explore n-tier deployment and
the data portal, data access, security, and how to use a business layer composed of domain objects
to create various types of application interface.

Using CSLA 4: Creating Business Objects Page 128


Rev 1.1

You might also like