Can Read/Write Property problem

Can Read/Write Property problem

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


xal posted on Tuesday, November 29, 2011

Hey everyone,

I've been fighting issues in migration of older csla apps to the latest. So far i've been able to work around (sometimes with some hacks) most of the issues related to the requirement of managed  properties in some scenarios and the dropping of instance rules.

The only issue I can not work around is CanReadProperty and CanWriteProperty. Currently it's string overloads are not virtual, so you can't override them and if the property you're referring to is not a managed property they will throw an exception. I think this calls for more flexibility, considering there's lots of scenarios where a property will not necessarily need a data store of it's own, will have no business rules and thus doesn't require a PropertyInfo object.

The strongest argument for changing this method is in my view that consumers of the business library won't necessarily know which properties will have backing PropertyInfo objects and which won't. If somebody were to call CanReadProperty("IsDirty") instead of getting the expected "true", you would get an exception for no reason. The problem is bigger when using readwrite authorization controls.

I think it would be a lot better if this could be changed to something more flexible, changing the string versions of CanReadProperty and CanWriteProperty to be overridable and not throwing an exception if there is no property info object, returning true by default. There's no reason to block execution if there's no explicit rule that makes a given property unavailable.

With those overridable versions you could make simple tests and check for simply:

if (!user.IsInRole("CanReadThisObjectsProperties")) { return false; }

That way you don't worry about specific properties and everything gets blocked. I've got scenarios where the principal might change during the lifetime of the application. Because another user signs in objects that were available to the previous user for getting are now loaded in memory and perhaps even bound to an open form. This scenario would let me block the user from interacting with the object, but it's currently impossible to achieve.

 

Cheers

Andres

 

JonnyBee replied on Wednesday, November 30, 2011

Hi Andres,

Considering that Windows Forms support may be removed for CSLA - I'm not sure how much of these changes are going to make it into the CSLA code base. I do agree that these changes should have been in CSLA 4.x for better support for  windows forms.

I am in the same process of migrating an application to CSLA 4 and have made these changes:

1.    Add ValidationRules (and BusinessRules extensions) to CSLA  to support “old” style validation rules.

2.    Change CanReadProperty(string)/CanWriteProperty(string) to virtual in CSLA.

3.    Create intermediate base classes (if you do not have them already).

4.    Add overloads to intermediate base classes:

1.    Add RegisterProperty overload to intermediate base classes that accepts string as first parameter.

2.    Add LoadProperty overload to intermediate base classes to support the old style LoadProperty.

3.    Add CanReadProperty/CanWriteProperty overloads to that return true if propertyName is not a registered property
ReadWriteAuthorization may else get an exception.

5.    Change to use new style AuthorizationRules (overrides on CanReadProperty/CanWriteProperty will still work).

6.    CommandObjects now make a copy (serialize) before calling Execute (ie all fields must be serializable).

7.    CriteriaBase is now a generic base class and must have generic constraint.

8.    SingleCriteria should be removed – is considered obsolete in 4.x.

9.    All BO/CommandObjects/CriteriaBase objects should have managed properties only.

10.  Add Csla.Validation.BrokenRulesCollection to support BindingList based broken rules..

11.  Update Csla.Validation.BrokenRulesCollection.Merge method to accept Csla.Rules.BrokenRulesCollection as parameter.

12.  Add constructor overload to BrokenRule(string source, BrokenRule rule) for usage in Csla.Validation.BrokenRulesCollection

These steps is to make the application compile and run in CSLA 4 - then have a larger team of developers to get into rewriting the business rules.  The changes above can (from my eperience) at most be done by 2 developers as it requires systematical changes to a lot af classes. We also created several ReSharper Structural Search and Replace patterns to migrate the code .

xal replied on Wednesday, November 30, 2011

Thanks Jonny, I am aware of those steps and I have already migrated most of the code. I have made some of those changes myself, but what I'm suggesting is that the default implementation of canreadproperty and canwriteproperty be changed to be virtual and to not throw an exception if there's no managed property and return true in that case.

This is not really related to winforms. The same could happen in asp, mvc, wpf or any other platform... If you use a something else similar to the readwrite authorization control in windows forms, or if you're using reflection to get all properties and call CanReadProperty or if you explicitly call CanWriteProperty with a property name you shouldn't get an exception if there's no managed property for a real property.

 

The fact that there's no managed property means that there can be no rule to say that you can't read or write to a given property, so that's why I'm suggesting that the most logical behavior is for it to return true instead of failing. Don't you agree?

 

Andrés

JonnyBee replied on Wednesday, November 30, 2011

I absolutely agreee with you, Andrés. 

PropertyStatus and PropertyInfo (both in Csla.Xaml)  use the CanReadProperty(string) and CanWriteProperty(string) and these methods should not throw exceptions if there is no corresponding registered PropertyInfo.

RockfordLhotka replied on Wednesday, November 30, 2011

fwiw, the string overloads are planned for removal in the future.

The decision to firmly move toward a pure PropertyInfo based model was part of my CSLA 4 design, and the reason that some of the string-based functionality has limitations is because I view them as effectively obsolete. I didn't remove them, because I didn't want to break certain existing functionality as part of the version 4 release.

It is quite possible that 4.5 will be the point where those overloads go away entirely.

xal replied on Wednesday, November 30, 2011

Does that mean that in the future the PropertyInfo objects will be exposed to consumers of the business object? Is there already an api for listing out the property info objects for a BO that I'm not aware of? Or do we need to use reflection to get the property info objects associated to a property name?

To be honest, I'm not so sure I understand this shift in direction. I really liked the property info concept when it was introduced because it has a lot of really good benefits. But I also find that it has limitations as well and originally they were not a problem because they weren't imposed, we could use the best of both worlds.

Every data binding stack out there relies on the property name string so in a way it would make sense to stick to that even though it's imperfect. I realize it's probably way too late to start a discussion on this matter, but I'm just trying to "get it". I'm not sold on the 100% managed properties.

 

Cheers!

RockfordLhotka replied on Wednesday, November 30, 2011

I should probably be a bit more clear.

My plan is that all properties are described by PropertyInfo fields. Those fields should be public (now and in the future).

The old string-based API used to manually implemented property get/set code from CSLA 1.x and 2.x is what will entirely go away.

The string-based overloads of some methods required by the UI (necessary so the UI can retrieve rule information) will remain, but with the current implementation - so they'll translate the string name into the appropriate PropertyInfo object and then delegate to the real implementation. That's what happens now, and that isn't slated to change.

To put it another way, any remaining string-based methods will delegate to the real methods that are PropertyInfo based. We started this in 4.0, and I plan to continue down this road.

In 4.5 the existing metastate properties (like IsDirty) will become managed properties with PropertyInfo fields and standard event handling, etc. In other words, they'll become bindable properties. This may make Windows Forms binding perform worse, because I'm not entirely sure we can avoid some duplicate PropertyChanged events from being raised as part of normal processing, and that'll result in more rebinding. But it will make XAML binding much simpler in some cases.

Copyright (c) Marimer LLC