Version 2.1 (VB only) available for testing

Version 2.1 (VB only) available for testing

Old forum URL: forums.lhotka.net/forums/t/776.aspx


RockfordLhotka posted on Monday, July 31, 2006

I have put a very early version of 2.1 on the downloads page. While many of the changes exist in both the VB and C# code bases, I've been doing all the experimental stuff around validation rules in only the VB code base, so that's all I'm putting up there at the moment.

(If there's demand, I can put the C# code up there too - but it is missing the validation/authorization rules changes - they are so extensive that I want to make sure they are good before going through the work of porting them over. FWIW, I wrote several other features in C# first, but they are stable enough that I just ported them back to VB already - things like FilteredBindingList and EditableRootListBase for instance.)

At the moment there's no real documentation beyond the change log. My plan is to write a new "chapter" describing the changes and how to use them. That content will be available for purchase on my web site when it is complete, and can be viewed as an add-on to the existing book. As always, the version 2.1 code will be freely downloadable just like 2.0. Basically I'm planning to follow the same model as I've been doing for years now - charge for the book (and now additional content) and provide the code freely.

If you want to experiment with, and help me test, the rather extensive changes to the validation rules I really appreciate it. These changes include:

  1. Per-type rules (call AddSharedRule() from the AddSharedBusinessRules() virtual method)
  2. Severities (set e.Severity in your rule method, retrieve Warning and Information items from BrokenRules)
  3. Priorities (set rule priorities in AddRule() and AddSharedRule() - 0 is high, bigger numbers are lower)
  4. Short-circuting (set ValidationRules.ProcessThroughPriority to indicate at which priority rules will no longer be processed if a previous rule (for the current property) is broken (Error severity). The default is 0, meaning all 0 priority rules are always processed, but priority 1+ are only processed if no previous rules are broken)
  5. Forced short-circuit (set e.StopProcessing to True in your rule method to prevent any subsequent rules from being processed for this property)

The per-type rules also applies to AuthorizationRules, where there's a new virtual AddSharedAuthorizationRules() method in which you can call the new SharedAllowRead(), etc. methods.

The per-type rules offer substantial performance and memory consumption benefits over the original per-instance approach, and I recommend migrating to this new approach unless you have a very specific need to customize your rules per instance. You can use both, but there's a performance impact to doing so, and so I recommend using only one or the other (preferably per-type).

The priority/short-circuiting also allows you to get major performance gains. For instance, you could do all your trivial rule checking (like string required, mas length, min value, etc.) and only do expensive rules (that might require database access, etc.) if the easy ones succeed. Also, with e.StopProcessing, you can have some rule decide that its failure was so important that no other rules should be checked, which offers a lot of flexibility.

The Warning and Information severities reflect a long-requested feature. I'm not sure I'm done here, as I still may add a new interface to Csla.Core.BusinessBase to expose these in a way more similar to IDataErrorInfo. However, I might not do that either, because it is just as easy to create an extender control to run off BrokenRules as off some new custom interface...

The real point though, is that only Error severity items will appear in an ErrorProvider control. If you want to display Warning or Information items you'll need to create your own UI mechanism to do that, and the information you need should be available from BrokenRules on each business object.

 

Q Johnson replied on Monday, July 31, 2006

I love the idea of you charging for the extra chapter for 2.1.  I wish you had started that in 1.x because there were some significant differences even between 1.3 and 1.0, never mind 1.5 and 1.3.  It wasn't always easy to "get it" from the change logs. Your own words about those changes and how to bring value to our projects by taking advantage of them will be extrememly valuable.  So you can bet we'll be happy to pay.
 
And you get some compensation for these great efforts for us.
 
Talk about win-win!!

skagen00 replied on Monday, July 31, 2006

I want to include my support for the prospect of charging for the documentation of 2.1.

I think there are a lot of us that recognize the value in what you give to us and would rather see a vendor (that'd be you in some ways, Rocky) feeling that it is worth their while to continue on this process of continual development. While some of that is just your love for Csla, I'm sure some compensation for your hard work is icing on the cake.

Thanks again.

(Oh, and once ported to C# I'll be immediately bringing 2.1 into the code base since we're quite a ways from production, yet.)

 

RockfordLhotka replied on Monday, July 31, 2006

Even if you normally use the C# version, you might try binding your code temporarily against the VB version to try the new features. They should be interchangeable at that level - my nunit test suite is the same for both VB and C#.
 
The reason I suggest this, is that by the time I port the changes to C# they'll be pretty well set in stone, so the opportunity for feedback is over the next week to 10 days. (but no pressure <g>)
 
Rocky

kids_pro replied on Monday, July 31, 2006

I love the idea of charging for 2.1 extra chapter.
I am looking forward to purchase your excellent works.
______________________________
Kids.

Fabio replied on Tuesday, August 01, 2006

Can you merge HEAD C# CVS prj with 2.1 branch ?
Thanks.
Fabio.

P.D. I know the warning: As always, be aware that this is a live repository, so there is no guarantee that the current code is tested or works in any way!!!

RockfordLhotka replied on Tuesday, August 01, 2006

Why would I do that? I've merged the 2.0.3 changes into 2.1 as I've made them, so 2.1 is 2.0.3 plus the new stuff.
 
Or are you suggesting merging the 2.1 changes back into HEAD? I will do that when 2.1 is complete, but there is still the possibility that I will need to create a 2.0.4 if someone discovers a bug that needs immediate fixing.
 
Rocky


From: Fabio [mailto:cslanet@lhotka.net]
Sent: Tuesday, August 01, 2006 12:09 AM
To: rocky@lhotka.net
Subject: Re: [CSLA .NET] Version 2.1 (VB only) available for testing

Can you merge HEAD C# CVS prj with 2.1 branch ?
Thanks.
Fabio.

P.D. I know the warning: As always, be aware that this is a live repository, so there is no guarantee that the current code is tested or works in any way!!!


Ben303 replied on Tuesday, August 01, 2006

Rocky, could you please extend the RuleArgs to contain a PropertyText property?

With the current structure it is difficult to localize user oriented texts within the rules framework. For example you might have a property called TargetDelivery that is labeled "Target delivery date" or "Gezielte Lieferdatum" throughout your application. A PropertyText property would return a localized or user friendly text (if set). If the value is not set (PropertyText=String.Empty), the property returns the PropertyName. You use the PropertyText value (as opposed to PropertyName) for the description returned after evaluating rules.

Thus, in RuleArgs you have:

  Private mPropertyText as String

  ''' <summary>
  ''' The human readable, localized name of the property.
  ''' </summary>
  Public Property PropertyText() As String
   Get
    If mPropertyText Is Nothing OrElse mPropertyText = String.Empty Then
     Return mPropertyName
    Else
     Return mPropertyText
    End If
   End Get
   Set(ByVal Value As String)
    mPropertyText = Value
   End Set
  End Property

And add a constructor
  ''' <summary>
  ''' Creates an instance of RuleArgs.
  ''' </summary>
  ''' <param name="propertyName">The name of the property to be validated.</param>
  ''' <param name="propertyText">The human readable, localized name the property to be validated.</param>
  Public Sub New(ByVal propertyName As String, ByVal propertyText As String)
   mPropertyName = propertyName
   mPropertyText = propertyText
  End Sub

You would change the CommonRules to use PropertyText instead of PropertyName.

For example in CommonRules you would change
 
    Public Function StringRequired( _
      ByVal target As Object, ByVal e As RuleArgs) As Boolean

      Dim value As String = _
        CStr(CallByName(target, e.PropertyName, CallType.Get))
      If Len(value) = 0 Then
        e.Description = _
          String.Format(My.Resources.StringRequiredRule, e.PropertyText)
        Return False
      Else
        Return True
      End If

    End Function

You would change the Functions and the constructors for the other CommonRules as well.

I still need to think about e.StopProcessing. I have a feeling yet another method is necessary. The ability to completely defer the evaluation of a rule until either requested or before saving. I'll see if I can work up some code for what I mean.

xal replied on Tuesday, August 01, 2006

Ben,
I agree with you that a way for specifying a friendly name for the property would be nice!!

About your request to validate on demand or before save, you can currently do that.
Add a rule that is not linked to any property name. For the example well use "MyValidationProp"

You can make a method like:

Public Sub ValidateThatThing() 'on demand validation
    ValidationRules.CheckRules("MyValidationProp")
End Sub

Public Overrides Function Save() As MyBO 'validate before save
    ValidationRules.CheckRules("MyValidationProp")
    Return MyBase.Save
End Function



Andrés

RockfordLhotka replied on Tuesday, August 01, 2006

That is an interesting idea, but I think you can address this in a broader and more encapsulated manner. It is not the responsibility of RuleArgs to do property name translation, so adding this code (simple though it seems) is outside the scope of RuleArgs job.
 
What is needed is a PropertyNameTranslator or PropertyNameMapper, that has the ability to take a fully qualified property name and translate it into some other text. The rule methods could then directly use this PropertyNameTranslator - and any other code that interacts with property names could do the same thing.
 
On the surface this PNT seems easy enough - but I fear the devil is in the details. Ideally it would use a resource file, but it obviously can't use the Csla.dll resources, so it would need to access some specific resource file name. Or get the values from a database, because some people would want that.
 
So really it needs to rely on a pluggable provider. So PNT would merely delegate the work to some provider, allowing you to write one that goes to a database, to a resource file, to a hard-coded list or whatever makes you happy.
 
I don't know that I'll have time to build and test such a thing in time for 2.1, but it is certainly an interesting idea.
 
Rocky


From: Ben303 [mailto:cslanet@lhotka.net]
Sent: Tuesday, August 01, 2006 8:38 AM
To: rocky@lhotka.net
Subject: Re: [CSLA .NET] Version 2.1 (VB only) available for testing

Rocky, could you please extend the RuleArgs to contain a PropertyText property?

With the current structure it is difficult to localize user oriented texts within the rules framework. For example you might have a property called TargetDelivery that is labeled "Target delivery date" or "Gezielte Lieferdatum" throughout your application. A PropertyText property would return a localized or user friendly text (if set). If the value is not set (PropertyText=String.Empty), the property returns the PropertyName. You use the PropertyText value (as opposed to PropertyName) for the description returned after evaluating rules.

xal replied on Thursday, August 03, 2006

Hey Rocky, I found an issue...

    Public Sub CheckRules(ByVal propertyName As String)

      Dim rules As ValidationRulesManager = RulesToCheck
      If rules IsNot Nothing Then
        Dim list As List(Of IRuleMethod) = rules.GetRulesForProperty(propertyName, False).GetList(True)
        If list IsNot Nothing Then
          CheckRules(list)
        End If
      End If

    End Sub

The bold code fragment could return null if you call rules for a property that doesn't have any... That's what the "If list IsNot Nothing" is for,,, but at the end of that bold fragment you do a .GetList(True) and that throws a null reference exception.
Maybe you can call a SortList() method call inside the If and before CheckRules(list)...

Andrés

RockfordLhotka replied on Thursday, August 03, 2006

I checked in a fix,thx.

----- Original Message -----
From: xal
To: "rocky@lhotka.net"
Subject: Re: [CSLA .NET] RE: Version 2.1 (VB only) available for testing
Date: Thu, 03 Aug 2006 13:54:18 -0500

Hey Rocky, I found an issue...

    Public Sub CheckRules(ByVal propertyName As String)

      Dim rules As ValidationRulesManager = RulesToCheck
      If rules IsNot Nothing Then
        Dim list As List(Of IRuleMethod) = rules.GetRulesForProperty(propertyName, False).GetList(True)
        If list IsNot Nothing Then
          CheckRules(list)
        End If
      End If

    End Sub

The bold code fragment could return null if you call rules for a property that doesn't have any... That's what the "If list IsNot Nothing" is for,,, but at the end of that bold fragment you do a .GetList(True) and that throws a null reference exception.
Maybe you can call a SortList() method ca ll inside the If and before CheckRules(list)...

Andrés





Brian Criswell replied on Saturday, August 05, 2006

Would it be possible to turn on the XML comments by default in the C# project?  I do not know if it is on by default in the VB project.

RockfordLhotka replied on Saturday, August 05, 2006

It is the way the VS project templates work. The C# template does a couple very odd things - like turning CLS compliance off (wtf?) and turning XML comments off. Both defaults seem backward to me, and the VB templates (imo) are more correct...
 
The comments will be turned on in 2.1, though I don't know for sure that I'll have time to go through and fix all the warnings that presently exist... It is amazing how rapidly time flies by, and how much work there is to put together a release.
 
I am still hoping to have a beta out at the end of August, but that may have to slip (at least in terms of fit-and-finish and any sort of templates/ProjectTracker being ready by then).
 
Rocky
 


From: Brian Criswell [mailto:cslanet@lhotka.net]
Sent: Saturday, August 05, 2006 2:10 PM
To: rocky@lhotka.net
Subject: Re: [CSLA .NET] RE: Version 2.1 (VB only) available for testing

Would it be possible to turn on the XML comments by default in the C# project?  I do not know if it is on by default in the VB project.



Brian Criswell replied on Monday, August 07, 2006

Would it be possible to change the behaviour of BusinessListBase<T>.IsDirty?  If a list has had items that have been subsequently deleted, is it really dirty?  For instance, someone could add an item to a DataGridView and then hit escape.  The item has been added and removed, and the list has stayed the same.  I propose that IsDirty be modified slightly.

public bool IsDirty
{
    get
    {
        // Deleting items that exist in the data source make us dirty
       for (int i = 0; i < DeletedList.Count; i++)
          if (!DeletedList[ i].IsNew)
             return true;

        // run through all the child objects
        // and if any are dirty then then
        // collection is dirty
        foreach (C child in this)
            if (child.IsDirty)
                return true;
        return false;
    }
}

RockfordLhotka replied on Monday, August 07, 2006

That's an interesting idea Brian. My only concern here is whether there's an issue with edit levels. I'd need to run through some models to make sure just checking IsNew is enough (specifically that a check for EditLevelAdded isn't required).

Brian Criswell replied on Friday, August 11, 2006

I realise that it may be getting ridiculously late for suggestions, but...

I was thinking about the shared authorisation rules.  Would it make sense to make a SecurityManager object that handled whether a user was allowed to Create, Fetch, Update or Delete a type of object?  It would allow the BO developer to write code in the static constructors of business objects (or a rule list on application load) similar to the SharedAuthorizationRules.AllowRead().

public class ObjectAuthorizationManager
{
    // Create
    AllowCreate(string propertyName, Type objectType, params string[] roles);
    DenyCreate(string propertyName, Type objectType, params string[] roles);
    CanCreateObject (Type objectType);

    // Fetch...

    // Update...

    // Delete...
}

This would allow the security checks that normally have to be made by overriding methods such as Save() to be built into the framework.  Save(), Delete, a base implementation of AddNewCore that just checked the security might all be possible.

Copyright (c) Marimer LLC