CSLA-Validation–the new NuGet package in CSLA .NET 4.5.40

Or how to use the Csla 3.6 to 3.8 style rules in Csla 4.5.40

Introduction

Many developers find the move from Csla .NET 3.x to Csla .NET 4.x to be a big hurdle. Especially when it comes to the new rule engine in Csla .NET 4.x. In this article I will take the ProjectTracker.Library project from the Csla .NET 3.6 samples and upgrade to .NET 4.5 with Csla 4.5.40 NuGet packages.

The 3.x rule engine used static methods and the new 4.x rule engine uses classes. The benefit of using classes is inheritance, testability and allow the framework to provide base classes that get to the inner properties and methods of the business objects. The new rule engine also provides the same base classes and signature for both sync and async rules.

Having done several migrations with different approach to how to do the migration (starting with having the “old” Csla in a private renamed assembly and namespace) I finally came up with the idea of how to support most of the older style rules within the new rule engine. As it turns out this was quite simple to do and only required 1 to 3 days of work to get the application up and running on the new version and then the entire team could start to work on migration of the rules.

In order to do a full migration there is several breaking changes that you must handle. These will be covered in a separate blog posts, so for now let us focus on getting the business library with old style rules to work. And keep in mind – your target platform may be . NET 4, .NET 4.5, Silverlight 5, Windows Store or MonoAndroid.

Important breaking changes for rules:

  • There can be only one Authorization rule per AuthorizationAction and IMethodInfo (or property) where the old rule engine allowed multiple rules and both Allow/Deny combinations.
  • AddAuthorizationRules() is now deprecated and these authorization rules should be moved to AddBusinesRules().
  • Rewrite authorization rules to use the new IsInRole() or IsNotInRole() rules.
  • Rewrite asynchronous rules to use the new rule classes.

The changes the we must do is:

  1. Remove references to old Csla assembly and add Csla references from NuGet
  2. Add intermediate base classes if not already present in solution
  3. Add usings to business objects
  4. Change the signature of CanReadProperty, CanWriteProperty and CanExecuteMethod
  5. pdate AuthorizationRules to new IsInRole/IsNotInRole rules
  6. Add usings to business objects
  7. Change the signature of CanReadProperty, CanWriteProperty and CanExecuteMethod pdate AuthorizationRules to new IsInRole/IsNotInRole rules

Step 1: Remove references to old Csla assembly and add Csla references from NuGet

Remove the references to Csla.dll and update target framework for this sample to .NET 4.5.

Then install nuget package csla-updateValitation in ProjectTracker.Library

See: https://www.nuget.org/packages/CSLA-UpdateValidation

For my own preference I changed the solution so that only

  • ProjectTracker.DalEf
  • ProjectTracker.DalLinq
  • ProjectTracker.Library

will be compiled.

Step 2: Add intermediate base classes for BusinessBase and ReadOnlyBase

The first step you must do is to add your own intermediate base classes for Csla business objects, if not already present in you solution. Make sure that these classes inherit from Csla.Validation base classes for BusinessBase and ReadOnlyBase. When your app is fully migrated to Csla 4.x you should change the inheritance to use the standard Csla base classes and remove the reference to Csla.Validation.

[Serializable()]
public class MyBusinessBase<T> : Csla.Validation.BusinessBase<T> where T:MyBusinessBase<T>
  {
    protected override void AddBusinessRules()
    {
      AddAuthorizationRules();
      base.AddBusinessRules();
    }

    [Obsolete("Move code to AddBusinessRules for CSLA 4.x")]
    protected virtual void AddAuthorizationRules()
    {
    }
  }
[Serializable()]
public class MyReadOnlyBase<T> : Csla.Validation.ReadOnlyBase<T> where T:MyReadOnlyBase<T>
  {
    protected override void AddBusinessRules()
    {
      AddAuthorizationRules();
      base.AddBusinessRules();
    }

    [Obsolete("Move code to AddBusinessRules for CSLA 4.x")]
    protected virtual void AddAuthorizationRules()
    {
    }
  }

And make sure that all you business objects and readonly objects inherit from these base classes.

Also take not of how you can add support for AddAuthorizationRules in your own intermediate base class.

Step 3 Add usings to business objects

You should now take the opportunity to add these usings to business objects

using Csla.Validation;
using Csla.Rules;

Step 4: Change the signature of CanReadProperty, CanWriteProperty and CanExecuteMethod

to use the overload that accepts a PropertyInfo or MethodInfo as parameter

Here shown for CanExecuteMethod()

From:

public Resource GetResource()
    {
      CanExecuteMethod("GetResource", true);
      return Resource.GetResource(GetProperty(ResourceIdProperty));
    }

To:

private static MethodInfo GetResourceMethod = RegisterMethod(p => p.GetResource());
    public Resource GetResource()
    {
      CanExecuteMethod(GetResourceMethod, true);
      return Resource.GetResource(GetProperty(ResourceIdProperty));
    }

and take note of how you can get rid of the string constant.

Step 5: Update AuthorizationRules to new IsInRole/IsNotInRole rules

and keep in mind that you can only have one rule per AuthorizationAction and methodinfo.

From:

protected static void AddObjectAuthorizationRules()
    {
      AuthorizationRules.AllowCreate(typeof(Project), "ProjectManager");
      AuthorizationRules.AllowEdit(typeof(Project), "ProjectManager");
      AuthorizationRules.AllowDelete(typeof(Project), "ProjectManager");
      AuthorizationRules.AllowDelete(typeof(Project), "Administrator");
    }

To:

protected static void AddObjectAuthorizationRules()
    {
      BusinessRules.AddRule(typeof(Project), new IsInRole(AuthorizationActions.CreateObject, "ProjectManager"));
      BusinessRules.AddRule(typeof(Project), new IsInRole(AuthorizationActions.EditObject, "ProjectManager"));
      BusinessRules.AddRule(typeof(Project), new IsInRole(AuthorizationActions.CreateObject,"ProjectManager", "Administrator"));
    }

and take note of how we can supply multiple rows on the last rule.

Then do the same updates for Resources.cs

Step 6: Update async rules to use new style classes

See this blog post by Rocky Lhotka on how to write an async business rule

http://www.lhotka.net/weblog/ImplementingAnAsyncRuleInCSLA4Version45.aspx

Step 7: Misc changes for Csla 4.5

Next there is a couple of changes that must be done.

CriteriaBase now has a generic constraint so code must be updated to:

    [Serializable()]
    private class ExistsCommand : CommandBase<ExistsCommand>
And the Windows Forms (BindingList) based classes has been renamed to BusinessBindingListBase and ReadOnlyBindingListBase.
The Csla 4.5 list classes now inherit from ObservableCollection and has slightly different signature on AddNew and events. 
So change from:
BusinssListBase  ==> BusinessBindingListBase

ReadOnlyListBase ==> ReadOnlyBindingListBase

Summary

So this showed how to make the old ProjectTracker.Library compile with Csla .NET 4.5 in .NET 4.5 and use (most) the old style rules. The tecnhique behind this is a set of extension methods that provide the “old” methods and wraps the static methods with a lamda rules. If you want to look at the actual code, the source code can be downloaded from github: https://github.com/MarimerLLC/csla

There is still a number of changes to be done in order to make the entire solution run and this will be a subject for more blog posts.

Hope this encourages you to start migration of your application to Csla .NET 4.5

Advertisements

4 thoughts on “CSLA-Validation–the new NuGet package in CSLA .NET 4.5.40

  1. Tom Woodforde

    Cannot thank you enough for posting this, it has been so helpful. One note: I had to add the [Serializable()] attribute to the intermediate class to get it to save through the dataportal. I.e.

    [Serializable()]
    public class MyBusinessBase : Csla.Validation.BusinessBase where T : MyBusinessBase

    Reply
    1. jonnybekkum Post author

      Yes, I didn’t include Serializable attribute in some my code samples.
      I have added the serializable attribute to the samples code now. Thank you.

      Did you use the CSLA-Validation nuget package?

      Reply
      1. Tom Woodforde

        Hi Jonny, yes I did, the 4.5.40 version. It’s been absolutely great, it’s allowed us to finally start migrating across to the latest version of CSLA and .net, which is a great relief. Many thanks for making it available.

        The only real issue we’ve come across on the validation side of things is that we were using Deny permissions rather than Allow and there are no Deny rules at the object level in Csla.Validation. Still, it is probably high time we switched our permissions model round, it just adds a bit of faff to the process as all the tables are named “DENIED_xxxx”.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s