Rockford Lhotka
    CTO at Magenic
    Author, speaker, software architect
    Creator of the CSLA .NET framework

About me
Contact me


Version 3.5.0 change log


This document is the change log for version 3.5.0 of CSLA .NET.


Breaking Changes:

The following is a summary of known breaking changes from version 3.0 to 3.5, ordered with the broadest impact items at the top:




Microsoft .NET 3.5 and Visual Studio 2008 required

You must upgrade your project to .NET 3.5 and use VS 2008.

CanReadProperty(), CanWriteProperty() and PropertyHasChanged() overloads that do not take the property name are now obsolete

You need to explicitly provide the property name to these methods, or better yet, use the new PropertyInfo<T> technique

Rename AddDependantProperty() to AddDependentProperty()

You need to globally change the name of this method

AutoCloneOnUpdate now defaults to true

If you depend on the value being false you must add this setting to your app.config file

EditableRootListBase.SaveItem() now returns a value

If your code overrides SaveItem() you’ll need to change your override to conform to the new method signature

Csla.Wpf.Validator has been removed

You need to upgrade your XAML to use the new .NET 3.5 support for validation

Csla.Windows.BindingSourceRefresh has been updated

You must remove and re-add all BindingSourceRefresh controls on your forms

The data portal now includes a Delete<T> overload, which means that IDataPortalServer changed.

If you have created a custom data portal channel you will need to update your Delete() method implementation to conform to the new interface


Changes and Enhancements:


Source control (071003-C#/VB)

I have branched the source code in svn at this point.


Version 3.0.4+ is on a branch at svn:// This will be used for maintenance and bug fixes only.


The main trunk contains version 3.5 at svn://


Visual Studio 2008 (071031-C#/VB)

All solutions and projects are now Visual Studio 2008 versions. While back-porting to VS 2005 may often be possible, I’ll be doing all my work in 2008 and so have converted the projects forward. This is effectively a breaking change at design time.


.NET 3.5 (071031-C#/VB)

The Csla project now targets the .NET 3.5 framework. Visual Studio 2008 allows you to select different targets for compilation, but since CSLA .NET will incorporate support for LINQ, it needs to target .NET 3.5. This is effectively a breaking change at design time.


nunit (071031-C#/VB)

The cslatest project now uses nunit 2.4.4. The older 2.2 version didn’t work with VS 2008, and this seemed like a good time to upgrade to a current version in any case.


AutoCloneOnUpdate (071031-C#/VB)

AutoCloneOnUpdate now defaults to True. This means that, by default, objects are cloned when Save() is called and the data portal is running in local mode. This setting exists in 3.0.x, but defaulted to False for backward compatibility. This is a breaking change if you were using a local data portal with the previous default setting.


BusinessListBase (071031-C#/VB)

Honor the RaiseListChangedEvents flag and don't call OnListChanged() if the flag is false.


BusinessListBase (071031-C#/VB)

Get the property descriptor data from the correct type when raising the ListChanged event after deserialization.


List classes (071101-C#/VB)

Add ToArray() method to all list classes.


Data portal (071101-C#/VB)

Call MarkOld() before calling DataPortal_Fetch().


Authorization (071030-VB/071127-C#)

Change authorization so it calls a delegate to process IsInRole(), rather than calling principal.IsInRole() directly. The default delegate implementation will call principal.IsInRole(), but now CSLA can be extended by implementing a provider for this delegate that can answer the IsInRole() question in different ways if needed.


BusinessBase/ReadOnlyBase (071203-VB/080115-C#)

Implement helper methods to get and set property values. These helper methods automatically handle authorization, setting the property value and calling PropertyHasChanged() if appropriate. The result is that many lines of code can be saved for each property.


Also implement a PropertyInfo<T> concept to hold metadata about properties, like the property name, friendly name, default value, etc.


Properties now look like this:


<Serializable()> _

Public Class Person

  Inherits BusinessBase(Of Person)


  Private Shared DataProperty As PropertyInfo(Of String) = _

    RegisterProperty(Of String)(GetType(Person), _

    New PropertyInfo("Data", "Object data", String.Empty)


  Public Property Data() As String


      Return GetProperty(Of String)(DataProperty)

    End Get

    Set(ByVal value As String)

      SetProperty(Of String)(DataProperty, value)

    End Set

  End Property

End Class


You can also use private backing fields like this:


<Serializable()> _

Public Class Person

  Inherits BusinessBase(Of Person)


  Private Shared DataProperty As PropertyInfo(Of String) = _

    RegisterProperty(Of String)(GetType(Person), _

    New PropertyInfo("Data", "Object data", String.Empty)


  Private _data As String = DataProperty.DefaultValue


  Public Property Data() As String


      Return GetProperty(Of String)(DataProperty, _data)

    End Get

    Set(ByVal value As String)

      SetProperty(Of String)(DataProperty, _data, value)

    End Set

  End Property

End Class


In either case, notice the Shared/static field that contains property metadata. It could be Public in scope. In that case the UI could use the metadata too, which includes the property name and friendly name. And because this is executed code, the friendly name can be localized via a resource file.


The field could also come from an external class or object. Once initialized, the PropertyInfo object is read-only.


The new GetProperty() and SetProperty() helper methods handle authorization and PropertyHasChanged() calls automatically.


For backward compatibility, I won’t remove the current string-based overloads, but everywhere a property name is passed, CSLA .NET now supports providing a PropertyInfo<T> as well. For managed field values (as in the first example) only PropertyInfo<T> parameters are accepted.


Validation\ValidationRules (071203-VB/080115-C#)

Add overloads of AddRule() methods that accept a Csla.Core.IPropertyInfo parameter instead of property name and friendly name.


Security\AuthorizationRules (071203-VB/080115-C#)

Add overloads of AllowRead() and similar methods that accept a Csla.Core.IPropertyInfo parameter instead of property name and friendly name.


BusinessBase/ReadOnlyBase (071115-VB/071127-C#)

Mark obsolete the overloads of CanReadProperty(), CanWriteProperty(), CanExecuteMethod() and PropertyHasChanged() that don’t require an explicit property name parameter.


BusinessBase/ReadOnlyBase (071115-VB/071127-C#)

Remove Equals() and GetHashCode() overrides from base classes.


Make GetIdValue() virtual rather than abstract, so overriding it is optional.


Change ToString() to return base.ToString() if GetIdValue() returns null.


EditableRootListBase (071115-VB/071127-C#)

Change SaveItem() to return a reference to the new object resulting from the Save() method call. This is a breaking change if you have overridden SaveItem() in a subclass of ERLB.


SafeDataReader (071127-C# only)

Add an overload of IsDBNull() that accepts a string parameter to bring the code into parity with the VB implementation.


ApplicationContext (071127-C#/VB)

Moved the ApplicationContext file from the DataPortal folder to the root project folder so it better matches the namespace. Also, ApplicationContext has grown over time and no longer really belongs to the data portal in any realistic sense.


FilteredBindingList (071127-C#/VB)

Add an overload for ApplyFilter() that reapplies the current filter to the list.


BrokenRulesCollection (071127-C#/VB)

Add overloads for ToString() to accept an item separator string.


UndoableBase (071127-C#/VB)

Add virtual methods to notify a subclass before state is copied, undone or accepted.


BrokenRulesCollection/BrokenRule (071127-VB/C#)

Add a CreateCollection() factory to allow creation of an empty BrokenRulesCollection. Add a Merge() method to allow other BrokenRulesCollections to be merged into this newly created list. As the BrokenRule objects are merged into the collection, the rule names are changed to be unique based on a “source” value. So a rule like rule://method/property becomes rule://source.method/property. Since you supply the source value, you can provide a meaningful value for each business object’s broken rules.


BrokenRulesCollection (071127-VB/C#)

Add a Revision property to the collection that changes each time an item is added or removed from the collection.


SmartDate (071128-VB/C#)

Add constructors that accept a DateTimeOffset, and a ToDateTimeOffset() method. Also add CompareTo() and Subtract() methods for DateTimeOffset.


Web\CslaDesignerDataSourceView (071129-C#/VB)

Provide sample data for DateTimeOffset column types.


SmartDate (071130-VB/071205-C#)

Implement IConvertible interface, and also add a type converter (Csla.Core.TypeConverters.SmartDateConverter). The result is that the standard Convert class can now be used to convert SmartDate values to other types, or a converter can be obtained from TypeDescriptor to do the conversion.


Core\ISmartField, SmartDate (071130-VB/C#)

Add ISmartDate interface, which is implemented by SmartDate. This interface is used in the new GetProperty() and SetProperty() methods when the field type is an ISmartDate and the property type is String so the value can be converted automatically.


Validation\ValidationRules (071203-VB/C#)

Add a new overload of AddRule() like
public void AddRule<T>(RuleHandler<T, RuleArgs> handler, RuleArgs args)


Validation\ValidationRules (071203-VB/071205-C#)

Rename AddDependantProperty() to AddDependentProperty(), marking the older spelling as obsolete. This is a breaking change (you’ll get a compiler warning).


Core\BindableBase, BusinessBase (071205-VB/C#)

Implement INotifyPropertyChanging interface and call OnPropertyChanging() from PropertyHasChanged().


SmartDate (071205-VB/C#)

Implement IFormattable interface.


DataMapper (071205-C#/071207-VB)

Do better type coercion, using Convert.ChangeType() and if that fails using a value converter from the property type’s TypeDescriptor. Also treat string.Empty as null if the property type is a Nullable<T>. string.Empty and null now translate to a 0 value when being converted to a primitive type. The end result is that SmartDate now converts to/from string and DateTime, and some null value issues with FormView data binding should now be resolved. Also, due to the use of IConvertible and value converters, the overall process is more extensible.


Core\BusinessBase, ReadOnlyBase (071214-VB/C#)

Fix issue where per-type rules were "reloaded" over and over in the case that no per-type rules are ever added for a type.


Security\SharedAuthorizationRules (071214-VB/C#)

Fix a thread race condition problem.


Validation\SharedValidationRules (071214-VB/C#)

Fix a thread race condition problem.


Validation\ValidationRules (071214-VB/C#)

Change how rule methods are validated to prevent non-static methods anywhere in the inheritance hierarchy of the business object type from being used.


Validation\ValidationRules (071214-VB/C#)

Add the ability to suppress the behavior of CheckRules(). If SuppressRuleChecking is true then CheckRules() does no work (which also means PropertyHasChanged() won’t trigger rule checking, which also means SetProperty() won’t trigger rule checking). This property defaults to false. The idea behind this property is that a block-mode interface, such as a web UI, can suspend rule checking while all object properties are set, and then could invoke a complete run of all rules after all properties are set. A business object can support this concept by simply adding a couple new methods like:


Public Sub BeginBatchLoad()

  ValidationRules.SuppressRuleChecking = True

End Sub


Public Sub EndBatchLoad()

  ValidationRules.SuppressRuleChecking = False


End Sub


Using this technique, an interactive UI would ignore these methods and have normal behavior, but a web UI would call these methods to optimize how validation rules are executed, potentially resulting in better overall performance.


LINQ (071214-C#/080123-VB)

Add indexed LINQ capabilities so when a select is run over a BusinessListBase collection the query can be optimized using an index.


Data\ConnectionManager (071217-VB/080108-C#)

Added a ConnectionManager class that helps manage the use of connection objects that are shared by a parent and its child objects. This class uses ApplicationContext.LocalContext and helps address the issues faced when using the TransactionScope transactional model where it unnecessarily invokes the DTC when opening “multiple connections” to update a single object graph.


Data\ContextManager (071217-VB/080108-C#)

Added a ContextManager class that helps manage the use of LINQ data contract objects that are shared by a parent and its child objects. This class uses ApplicationContext.LocalContext and helps address the issues faced when using the TransactionScope transactional model where it unnecessarily invokes the DTC when opening “multiple connections” to update a single object graph.


SmartDate (071217-VB/080108-C#)

Implement casting operators to convert to/from various date related types. And implement SetDate() methods to make it easier to set the Date property using nullable date values and DateTimeOffset values.


Validation\CommonRules (071218-C# only)

Fix bug in StringMinLength.


Wpf\CslaDataProvider (080104-C#/VB)

Fix issue with returning exceptions and results.


Child objects (080108-VB/080114-C#)

Enhance the data portal so it knows how to create, fetch and update (insert/update/delete) child objects (single and collection). Enhance BusinessListBase and FieldDataManager to support this new data portal feature.


The result is that a typical child BusinessListBase subclass doesn’t need to implement any data access code. A root BusinessListBase subclass only needs to open the connection and make a single method call.


When using the new property management technique, a root BusinessBase subclass needs to make only one method call to update all child objects.


Child objects are now created or fetched using a comparable factory/data portal pattern to root objects, making object creation for all objects follow a single standard model.


Data Portal (080108-VB/C#)

Include an operation type property in the DataPortalEventArgs passed to the pre- and post-processing data portal methods. This allows the code in those methods to know which operation (create, fetch, update, delete, execute) is being executed.


MethodCaller (080108-VB/C#)

Add support for ParamArray/params parameters in target methods.


MethodCaller (080114-VB/C#)

Add support for single array parameters in target methods.


BusinessListBase (080109-VB/080114-C#)

Set RaiseListChangedEvents to false in UndoChanges() to prevent a lot of erroneous events during the process. Instead, a Reset event is now raised once at the end of the process.


Wpf\Validator (080114-VB/C#)

Remove the Validator control from CSLA .NET because Microsoft has provided an alternative in .NET itself. This is a breaking change for anyone using csla:Validator in a XAML page.


Data Portal (080114-VB/C#)

Ensure that the DataPortalComplete event is raised, even in the case of an exception. Also include the Exception object in the args parameter in that case.


Data Portal (080116-C#/080117-VB)

Pass business object type as part of DataPortalEventArgs.


Authorization (080116-C#/080117-VB)

Implement formalized object level authorization scheme. This way objects don’t need to implement the four static methods by convention. Instead, the object and UI code can always use static methods on Csla.Security.AuthorizationManager to determine whether the current user is allowed to create, get, edit or delete a given object type. Inside the business object, a single static method is implemented (AddObjectAuthorizationRules()) to specify the roles allowed/denied the right to create, get, edit or delete instances of the type.


Data Portal (080117-C#/VB)

Dispose proxy when released in ReleaseProxy() method.


Wpf\CslaDataProvider (080117-C#/VB)

Make CanExecuteNew() check authorization, returning false if the user isn’t authorized to edit the list object.


MethodCaller (080123-C#/VB)

Moved class to Csla.Reflection namespace and implemented major performance enhancement changes. Many of these changes were contributed by Ricky Supit, who put a lot of work into this – thanks Ricky!  MethodCaller now uses dynamic method delegates instead of raw reflection, and does a bunch of caching of these delegates, resulting in major performance gains over the use of simple reflection.


LateBoundObject (080123-C#/VB)

Another contribution by Ricky Supit, this is a convenient wrapper around other objects to make it easier to do high-performance late-bound method calls. It delegates to MethodCaller, but provides a cleaner interface.


Core\UndoableBase (080123-C#/VB)

Use full type name when creating the key for each value. This avoids a possible name collision in the hash table.


Core\BusinessBase (080124-C#/080201-VB)

Change the default DataPortal_Create() implementation to not throw an exception, but instead to call ValidationRules.CheckRules(), and to be marked as RunLocal. This means that in simple objects where no initialization is required, the business developer doesn’t need to override the method simply to call CheckRules().


Core\BusinessBase (080124-VB/C#)

Fix data binding bug with the deletion of child objects. When a child object is deleted, it is now marked as “unbound”, so the edit level processing works properly.


Windows\BindingSourceRefresh (080105-C#/080201-VB)

Update implementation to handle null values and for performance. This is a breaking change, because you must remove and re-add all BindingSourceRefresh controls on your forms.


Core\ITrackStatus (080216-VB/C#)

Add IsSelfDirty and IsSelfValid properties to the interface (and thus also to BusinessBase, BusinessListBase and FieldData).


Data\ConnectionManager,ContextManager (080222-C#/VB)

Add GetCurrentManager() method that returns a manager without reference counting. This method is for use in child objects only, and must not be used in a using block.


Also reversed the default meaning of the first parameter of GetManager() and GetCurrentManager(). The default meaning is now that the parameter is the database name not the connection string. This is a breaking change from Beta 1.


Data\ConnectionManager,ContextManager (080227-C#/VB)

Remove GetCurrentManager() method that returns a manager without reference counting. The training/support/confusion issues around this method are too great and I’m removing it to avoid them.


Wpf\CslaDataProvider (080227-C#/VB)

Add support for the Delete XAML command, which translates to a RemoveItem() call that removes an item from a data bound list. This eliminates the need to write code for a remove item button or link on rows in a list. So now no code is needed for Save, Cancel, Add New or Remove buttons in a UI.


Core\BusinessBase (080315-C#/VB) (RC1)

Change GetProperty<T> and SetProperty<T> so they accept an enum to specify whether to throw an exception if the user isn’t authorized to see/change the property. This avoids an overload conflict when working with bool type properties. This may break some code written against Beta 1 or Beta 2.


Data\ConnectionManager & ContextManager (080315-C#/VB) (RC1)

Throw a meaningful exception if the database name can't be translated into a connection string from the config file.


DataPortal\ChildDataPortal (080315-C#/VB) (RC1)

If object to update is null then just return. This makes it simpler to write parent insert/update methods because the parent doesn't need to do a null check on the child.


Core\FieldManager (080328-C#/VB) (RC2)

Throw a meaningful exception on a failed attempt to access a property that hasn’t been registered. This replaces the hard-to-understand index out of range exception that was happening.


Wpf\DataDecoratorBase (080330-C#/VB) (RC2)

Fix a problem where a list data source would not have its events hooked properly in all cases.


Core\ExtendedBindingList (080330-C#/VB) (RC2)

Add an AddRange() method to allow adding a list of IEnumerable<T> items to the list.


DataPortal (080330-C#/VB) (RC2)

Add Delete<T> overload for use when calling DataPortal.Delete(). This will break any custom data portal channel implementations.



Known issues:


There is a known issue where the Visual Studio debugger will “lock up” (actually it will eventually crash due to a stack overflow) when an exception is thrown in the DataPortal_Fetch() of a subclass of ReadOnlyListBase.


The issue appears to be due to a bug in the Visual Studio debugger’s exception assistant.


The workaround is to click Tools|Options, then Debugging|General and uncheck the “Unwind the call stack on unhandled exceptions” box (You may need to check the “Show all settings” box at the bottom of the dialog to see this option).



When adding CslaDataSource to a page by choosing to “add a new data source” from within the GridView or DetailsView controls the data source control will not function properly in the designer, though it will appear on the page. (This is due to a bug in Visual Studio in terms of how it loads the control into memory, and I’ve discussed it with Microsoft.)

The workaround is to switch the designer to Source view and back after adding the new CslaDataSource control to a page. This will force the designer to reload the control, making it act properly within the designer.


As before, you can add a CslaDataSource to the page by dragging it directly from the Toolbox, or by typing in the tag manually. Both of these techniques work immediately with no known issues.



(Updated 3/30/2008 10:34:26 PM)