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?
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
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?
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?
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?
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:
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
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.
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...
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()?
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?
Copyright (c) Marimer LLC