To <type> or not to <type> (properties)?

To <type> or not to <type> (properties)?

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


esaulsberry posted on Friday, June 05, 2009

I've noticed there are a number of ways to declare and initialize properties and I'm wondering about why to choose one over another.  For example, you can declare the property info object for a string property Foo as

public static PropertyInfo<string> FooProperty = RegisterProperty(typeof(MyBusOb), new PropertyInfo<string>("Foo"));
or
public static PropertyInfo<string> FooProperty = RegisterProperty<string>(typeof(MyBusOb), new PropertyInfo<string>("Foo"));
or
public static PropertyInfo<string> FooProperty = RegisterProperty<string>(new PropertyInfo<string>("Foo"));

Like wise the GetProperty method could be:

get { return GetProperty(FooProperty); }
or
get { return GetProperty<string>(FooProperty); }

Any particular reason to choose one style over another?

sergeyb replied on Friday, June 05, 2009

Inside a business object I use the simplest syntax:

public static PropertyInfo<string> FooProperty = RegisterProperty(new PropertyInfo<string>("Foo"));

get { return GetProperty(FooProperty); }

 

 

If you are using a non-generic class such as CommandBase, then you need to use type of syntax

public static PropertyInfo<string> FooProperty = RegisterProperty(typeof(MyBusOb), new PropertyInfo<string>("Foo"));

 

Sergey Barskiy

Principal Consultant

office: 678.405.0687 | mobile: 404.388.1899

cid:_2_0648EA840648E85C001BBCB886257279
Microsoft Worldwide Partner of the Year | Custom Development Solutions, Technical Innovation

 

From: esaulsberry [mailto:cslanet@lhotka.net]
Sent: Friday, June 05, 2009 2:05 PM
To: Sergey Barskiy
Subject: [CSLA .NET] To <type> or not to <type> (properties)?

 

I've noticed there are a number of ways to declare and initialize properties and I'm wondering about why to choose one over another.  For example, you can declare the property info object for a string property Foo as

public static PropertyInfo<string> FooProperty = RegisterProperty(typeof(MyBusOb), new PropertyInfo<string>("Foo"));
or
public static PropertyInfo<string> FooProperty = RegisterProperty<string>(typeof(MyBusOb), new PropertyInfo<string>("Foo"));
or
public static PropertyInfo<string> FooProperty = RegisterProperty<string>(new PropertyInfo<string>("Foo"));

Like wise the GetProperty method could be:

get { return GetProperty(FooProperty); }
or
get { return GetProperty<string>(FooProperty); }

Any particular reason to choose one style over another?



decius replied on Tuesday, June 09, 2009

What was the purpose of Csla 3.6 RegisterProperty methods?  At first I thought, "Cool, this will condense code."  But after looking at it, I've actually had to write more code and learn a new technique just to implement these new methods. 

So, I'm just curious, what was the reason behind this?

JoeFallon1 replied on Tuesday, June 09, 2009

It has a number of uses.
1. It does condense code. By 60% or so.
2. It eliminates bugs from new devs who forget to make the various calls in the Property Set.
3. It allows Managed Properties to exist for Child objects. This eliminates an entire class of bugs where devs mess up the edit levels, etc.
4. Managed properties allow you to use restricted environments (like Silverlight) with no code changes! Since reflection is not allowed in those sandboxes, managed propeties allowed Rocky to develop the IMobileObject interface and its serializer/deserializer.

Joe

decius replied on Wednesday, June 10, 2009

Fantastic response.  I suppose I'll learn to get used to it and accept it then.  #4 is a great point that is definitely not immediately obvious.  I was just overwhelmed at the added complexity to simply initialize a member variable! 

one thing I was bothered with though, is that I usually put a lot of business logic in my getters and setters.  Is it appropriate to just do things like this?

public string SomeString
  {
   get {

string tmp = GetProperty(SomeStringProperty);

if(tmp == "something") return tmp;

else return string.Empty 

}

}
Other suggestions/opinions most welcome.  What are other people doing?

RockfordLhotka replied on Wednesday, June 10, 2009

The idea with the CSLA property syntax is that you would not put any extra logic in the get/set blocks.

If you have business or validation rules around your property values, they should be implemented using the business rule subsystem in CSLA - override AddBusinessRules() and add your rule methods to your properties.

JoeFallon1 replied on Wednesday, June 10, 2009

Rocky is right (as per usual.)
But what he is not stating here (and it is quite subtle) is that the CheckRules code does not always have to be used for validation! You can also attach it to a Property and use it as place to run custom logic (just always return True so the validation subsystem never knows you were really doing something else.)

Joe

tetranz replied on Wednesday, June 10, 2009

JoeFallon1:
Rocky is right (as per usual.) But what he is not stating here (and it is quite subtle) is that the CheckRules code does not always have to be used for validation! You can also attach it to a Property and use it as place to run custom logic (just always return True so the validation subsystem never knows you were really doing something else.) Joe


So are you saying that if I want an update of PropertyA to cause a change in PropertyB or do a calculation or whatever then doing it in a rule is a better place than overriding OnPropertyChanged?  I'm not necessarily disagreeing but I just wonder why you wouldn't use PropertyChanged.

RockfordLhotka replied on Wednesday, June 10, 2009

Rules run at times other than when the property changes. For example, rules often run when an object is created, sometimes before it is saved, etc.

In a web environment, you might consider disabling property notification (BypassPropertyChecks) when loading an object with postback data, then calling CheckRules() at the end. This can provide better performance characteristics in some cases.

And in such cases, relying on PropertyChanged to trigger business processing would be a problem, because that event may be suppressed, while CheckRules() does get called.

Also, I think it is more consistent and less obscure to implement all business/validation rules using the same technique, so I favor use of rule methods for this purpose.

I'm not saying OnPropertyChanged() is particularly bad, but there are some usage scenarios where it isn't ideal, and it doesn't provide overall consistency.

RockfordLhotka replied on Wednesday, June 10, 2009

I should say too, that I understand the confusion.

If I had it to do over again, I'd name the ValidationRules property BusinessRules, so instead of ValidationRules.CheckRules() you'd call BusinessRules.ExecuteRules() or something like that.

But changing that member name would break everyone, and so isn't very realistic.

The unfortunate side-effect, though, is that there's a very natural assumption that ValidationRules is all about validation rules. When the reality is that it is about both business and validation rules...

decius replied on Thursday, June 11, 2009

Whoa. Revelation.  I've been writing CSLA stuff for about a year now and that just blew my mind lol.  This will take some getting used to but it makes a lot of sense. It's almost like I just learned I've been putting my pants on backwards all these years...

Still some situations come up that I don't understand how you'd handle.  SmartDates for example, a lot of times, I'll want a specific string for IsEmpty values.  which amounts to a simple:

get{

if(_date.IsEmpty) return "This date is empty";

else return _date.Text;

}

How should this be done using AddBusinessRules()?

boo replied on Thursday, June 11, 2009

I have similar scenario's that I was wondering about too...looking forward to recommendations there...

ajj3085 replied on Friday, June 12, 2009

I almost think that's something that the UI layer should handle. The value of the property isn't "This date is empty" it's SmartDate.IsEmpty.

decius replied on Friday, June 12, 2009

Yes, on a architectual level, I would agree.  But on a practical level, when we databind to most of the controls we use, the control accesses these public properties of the business objects. 

Sure, a lot of situations like these can be handled by databindng format options on the controls, but in cases like this, where you return an empty value, there's no way to tell the binding to display a specific text for empty values (though sometimes there is for NULL values, but not empty strings from what I've encountered). 

Easy solution, just modify the get accessor.  But now I'm told that's unconventional.  What to do?

boo replied on Friday, June 12, 2009

And I'd agree with you; if you use this object on multiple forms you don't want to create the same GUI code in multiple places.   And what if the business object is part of report as in my case?   Well now I got to get our report generator to start throwing additional logic into it which isn't always easy; modifying the getter is the pragmatic approach we've used in the past and now again, we're in the situation you are.

Copyright (c) Marimer LLC