Wednesday, November 02, 2005
« Reenabling MSDTC under WinXP SP2 | Main | Helpful add-ins for Visual Studio »

Quite a few people have asked me about the effort that will be required to move an application from CSLA .NET 1.0 to CSLA .NET 2.0. The list of changes in the change log can look daunting after all…

 

Fortunately most of the changes in the change log are internal – they don’t directly impact your code in a business class all that much, at least for code written using more recent versions of the framework (1.3 or higher).

 

In fact, the closer your code is to version 1.51 (the current version) the easier the port will be. The closer to the original 1.0 version in the books the harder.

 

The three big change areas are generics, BrokenRules and the DataPortal.

 

Generics mean there are new and different base classes from which you inherit. In most cases changing to the new base class means removing some now unneeded code from your business class. The following table lists the base classes:

 

Old

New

BusinessBase

BusinessBase(Of T)

BusinessBase<T>

T = your business object type

BusinessCollectionBase

BusinessListBase(Of T, C)

BusinessListBase<T, C>

T = your collection type

C = child object type

NameValueCollectionBase

NameValueListBase(Of K, V)

NameValueListBase<K, V>

K = type of the key or name

V = type of the value

ReadOnlyBase

ReadOnlyBase(Of T)

ReadOnlyBase<T>

T = your business object type

ReadOnlyCollectionBase

ReadOnlyListBase(Of T)

ReadOnlyListBase<T>

T = child object type

 

The only place where you need to add code is BusinessBase(Of T), where there’s a new GetIdValue method you must implement (typically with one line of code). In all cases you will remove code such as the System.Objects overrides region and tons of code in collections.

 

A much bigger changes is that BrokenRules has been replaced by ValidationRules and now only supports the idea of rule methods. The BrokenRules.Assert() concept is gone. This will be the biggest change for most people, as all Assert calls must be converted to rule methods. Fortunately that's not terribly hard, but it is work.

 

DataPortal used to call DataPortal_Update, forcing you to write a nested If..Then statement inside DataPortal_Update. It now calls DataPortal_Insert, DataPortal_Update or DataPortal_DeleteSelf as appropriate. So now you write 3 methods instead of 1, but each method is very focused and requires no conditionals. Also, DataPortal now calls MarkNew and MarkOld automatically so you don't need to make those calls (or forget to make them like I typically did...).

 

The end result is that all properties in a BusinessBase(Of T) business object will now look like this:

 

private string _name = string.Empty;

 

public string Name

{

  get

  {

    if (CanReadProperty())

      return _name;

    else

      throw new System.Security.SecurityException(

        "Property get not allowed");

  }

  set

  {

    if (CanWriteProperty())

      if (_name != value)

      {

        _name = value;

        PropertyHasChanged();

      }

    else

      throw new System.Security.SecurityException(

        "Property set not allowed");

  }

}

 

Or

 

Private mName As String = ""

 

Public Property Name() As String

  Get

    If CanReadProperty() Then

      Return mName

    Else

      Throw New System.Security.SecurityException( _

        "Property get not allowed")

    End If

  End Get

  Set(ByVal value As String)

    If CanWriteProperty() Then

      If mName <> value Then

        mName = value

        PropertyHasChanged()

      End If

    Else

      Throw New System.Security.SecurityException( _

        "Property set not allowed")

    End If

  End Set

End Property

 

 

The new Expert VB/C# 2005 Business Objects books and thus the CSLA .NET 2.0 framework are slated for public release in Mar/Apr 2006.

Wednesday, November 02, 2005 6:31:01 PM (Central Standard Time, UTC-06:00)
I think you should consider adding a CanWriteProperty(bool throwOnFalse) and CanReadProperty(bool throwOnFalse) method to remove even more redundant code.
Friday, November 04, 2005 6:45:12 PM (Central Standard Time, UTC-06:00)
how are you handling the frustrating ObjectDataSource mentioned in the previous posts??
JB
Sunday, November 06, 2005 11:39:03 PM (Central Standard Time, UTC-06:00)
Nice idea Marc, I'll consider it.

JB, I'm still working on that issue. At this point in time it appears I'll be using a custom ASP.NET data source object that is designed to accomodate CSLA .NET objects. In talking to the ASP.NET team it sounds like this is the best option.

I don't mind that overmuch. There are some issues with Windows Forms data binding that have required the creation of a couple helper controls for that environment as well. The end result is well worth it!!
Monday, November 07, 2005 4:29:20 PM (Central Standard Time, UTC-06:00)
Rocky,
Will CSLA.NET 2.0 contain any of the "add on" features that exist in Petar's ActiveObjects? I remember reading one of your posts where you stated that you might consider adding some of the features like IObserver, Channels, etc. Just curious. I am very much looking forward to getting your new book :-) .

Chris
Chris Russi
Tuesday, November 08, 2005 10:38:59 AM (Central Standard Time, UTC-06:00)
I am not implementing an observer pattern, no. The DataPortal now supports pluggable channels or network transports in preparation for WCF, but that's about it.
Sunday, November 20, 2005 2:17:59 PM (Central Standard Time, UTC-06:00)
Have you considered implementing the base CSLA classes to support enlistment in transactions using the new System.Transactions extensiblity capabilities?

This artical on MSDN is excelent:
http://msdn.microsoft.com/msdnmag/issues/05/12/transactions/default.aspx

The specific use case is for when you perform an update on a collection in the DataPortal_Update and there is a failure. In order to support rollback today, the client must snapshot a copy, catch the exception and handle the rollback. The new transaction support would make it very easy for the data portal to support transaction changes to the business object.

Just a thought...
Tuesday, November 29, 2005 9:02:45 AM (Central Standard Time, UTC-06:00)
What happens if you have a BO where some properties can be viewed but others cannot be viewed due to security? If you throw an exception in any one of the properties then it would stop the whole BO from being displayed.

So, should the BO or BO's collection maybe publicly expose some CanReadProperty("PropertyName")/CanWriteProperty("PropertyName") methods. These would be needed so when CanWriteProperty= true we can set the bound control up to be readonly without it thowing an exception. When CanWriteProperty= true the control is either not bound and is hidden or it could display "Not autherized to view" text instead of the value (or any other message in the control).
John Lipman
Sunday, December 04, 2005 10:49:09 AM (Central Standard Time, UTC-06:00)
The CanReadProperty and CanWriteProperty methods are public, so the UI can use them to alter itself. For Windows Forms I'm actually providing an extender control that does this for you automatically (for the most part).

But throwing an exception doesn't actually stop the whole object from being displayed in Windows. The data binding handles this case transparently - though it is far better to use the extender control to disable/hide various controls.
Monday, December 05, 2005 11:34:29 AM (Central Standard Time, UTC-06:00)
I like Mark's suggestion as well. I'm not sure if you are familiar with the ArgumentValidation class from Enterprise Library, but it essentially works the same way. Before any method processing just call a few voids to validate the arguments then continue processing. Granted all your call stacks are off by one level, but it allows you to wrap common resource calls for exception messages in addition to just the logic for throwing of the exception, which I would think is more valuable then just wrapping the throw, and it makes it easier to manipulate the thrown exception from a single place.
Paul
Comments are closed.