I'm going through the MVVM video series and it occurred to me that it would be very nice if the ViewModel.BeginRefresh( string methodName ) method was capable of using a "non-magic string" syntax like like we do with the RegisterProperty convention?
The RegisterProperty scenario I'm referring to is this:
public static PropertyInfo<string> LastNameProperty = RegisterProperty<string>( c => c.LastName );
Would it be possible to do something similar for a method name? For example:
BeginRefresh( c => c.NewEmployeeEdit );
Possibly, another location also that could benefit from the Property version is the business rules section, but I haven't looked at the new CSLA 4.0 implementation in earnest yet.
It's usefull for us as it helps my team to not miss a reference to a property name / method name when there is renaming required, especially when it's in a "magic string" format.
I'm not sure whether this is even at all technically possible for method names and or whether there are other implications that need to be considered. Just though I'd raise the question since it appears to be of value in create a more concise and maintainable CSLA business object.
I think that's actually in there now. I remember it being a work item at least, though I didn't do it (maybe Peran did?).
Obviously that uses reflection to translate the lambda into an actual string name, but I suspect the perf hit is extremely trivial, and as you note, the maintainability is better.
This was implemented in Csla 4 ViewModelBase for DoRefresh (sync) and BeginRefresh (async) methods. There are examples of its use in the code comments.
/// <example>DoRefresh(() => BusinessList.GetList())</example>
/// <example>DoRefresh(() => BusinessList.GetList(id))</example>
protected void DoRefresh(Func<T> factoryMethod)/// <example>BeginRefresh(handler => BusinessList.BeginGetList(handler))</example>
/// <example>BeginRefresh(handler => BusinessList.BeginGetList(id, handler))</example>
protected void BeginRefresh(Action<EventHandler<DataPortalResult<T>>> factoryMethod)
That's just excellent!
It's very nice how the BeginRefresh for a Action does not have to concern itself with the parameters of the BO factory method as this is done in the call itself. Very clean indeed
I have peeked at the business rules API for CSLA 4 and it looks so much more concise and contained.
In line with this thread, would it make sense to have the Csla.Core.BusinessRule baseclass's constructor provide support for using a Lambda expression to reference the property to which the rule should apply.
This would then also follow onto the derived classes and further decendants. E.g. Csla.Rules.CommonRules.CommonBusinessRule and also the other built-in common rules.
I'm hoping for a usage pattern similar to RegisterProperty along the following lines:
BusinessRules.AddRule( new Csla.Rules.CommonRules.Required( c => c.LastName ) );
Again the same motivation applies - less dependency on "magic strings" and increased maintainability.
CSLA 4 requires the use of PropertyInfo<T> fields to avoid the magic string, and to avoid reflection.
There area a few cases where a string property name is still allowed, because data binding is all string-based, but normally your should expect to use a propertyinfo field.
The lambda thing isn't necessarily ideal. Its implementation requires the use of reflection. The whole idea of the propertyinfo fields is to do that reflection once per property for the entire life of the app, so we're not paying that cost continually as the app is being used.
You're totally right.
I missed the IPropertyInfo in the signature... cannot now figure how I thought it required a string parameter. My mistake... sorry for wasting your time!
Copyright (c) Marimer LLC