XPO_EasyFields and SetPropertyValue
EDIT (2010-10-12): This article is still valid, however I make a point about not being able to use it for Attributes, I have posted a beta version which allows you to set an option to generate Constants which then can be used in Attributes please look at this post for more information http://www.alfware.com.au/component/content/article/1-blog/43-minor-update-to-xpoeasyfields-beta
Now back to your scheduled broadcast....
OK guys, you know how much I HATE having “string” representations of my fields, IMHO it is the most dangerous part of your application, one wrong move with your refactoring and everything can turn to hell.
This is where I use XPO_EasyFields a lot, where you use “MyProperty” you can replace it with
MyObject.Fields.MyProperty.PropertyName
Yes I agree it is a tad longer ;) however the advantage is if you change your code you will end up with Compile error instead of nasty runtime errors that can be hard to identify.
So where can you use it? well pretty much anywhere! (The only place you can’t is in PersistentAlias ANY Attributes as .NET only allows constants and strings) :(
- Use it for DataBinding via Code where I specify the DataMember by using
- Use it for FieldName property of your GridColumn
- Use it to add properties to your XPView
- Use it when creating your Criteria
- Use it to build a “Add Field” menu for a selection of Fields to get from the Database
- Use it within the SetPropertyValue method call within the property itself
It is number 6 I want to discuss today.
Use it within SetPropertyValue, really?
It is quite simple really, how many times have you added the PersistentAttribute to your property to be your original property name, then refactor your property to a new name then forget to change that bloody string in the SetPropertyValue method call?
For example say I have
Private fMyProperty As String
Public Property MyProperty As String
Get
Return fMyProperty
End Get
Set(ByVal Value As String)
SetPropertyValue("MyProperty", fMyProperty, Value)
End Set
End Property
Then I want to change MyProperty to MyField instead, typically you add a PersistentAttribute to your property (so it binds to the original database field) and then rename your field (using CodeRush rename of course)
Private fMyField As String
<Persistent("MyProperty")>
Public Property MyField As String
Get
Return fMyField
End Get
Set(ByVal Value As String)
SetPropertyValue("MyProperty", fMyField, Value)
End Set
End Property
It is that simple to end up with an error in your code without easily noticing it, SetPropertyValue should have “MyField” not “MyProperty” so to get around this I use
SetPropertyValue(Fields.MyProperty.PropertyName, fPropertyName, Value)
this means in our example where I changed it to MyField when my FieldsClass gets updated with the new PropertyName, I will end up with a Compile error which will point me straight to the offending line.
Seems like a lot of work, CodeRush to the rescue
OK I myself am guilty of not following my own rule as it was frustrating to keep editing the property all the time after using the xp?type? template.
Well, I am daft, I have no idea why I haven’t done this before but all you need to do is
- Open up your CodeRush options CTRL+SHIFT+ALT+O
- Open Editor > Templates
- Search for #per
- Select the DevEx > XPO > System >
VB.NET
#PersistentPropertySet# item
C#
#PersistentPropertyBody# item - Change the SetPropertyValue call to
VB.NET
SetPropertyValue(Fields.«Link(PropertyName)».PropertyName, «:#PropertyVar#», Value)
C#
SetPropertyValu e(Fields.«Link(PropertyN ame)».PropertyName, ref «:#PropertyVar# », value); - Make sure you click OK to save your changes
Now when you use your xp?Type? template you will have your SetPropertyValue method setup ready to go with a compile error to start with (as the FieldsClass wouldn’t have been updated yet), so update your XPO FieldsClass and your compiler error will vanish.
However next time you refactor you will be safe in knowing that your compile error will come back should you forget a step :)
Happy XPO’ing
Latest Comments
- Simple Collection to...
Hey Norman, Keep in mind that Baritem ar... More... - Simple Collection to...
Great many thanks - this said, I'm looki... More... - Simple Collection to...
I just checked my class here and it stil... More... - Simple Collection to...
I'm using Winform DevExpress Library - a... More... - XPO ObjectLayer Tuto...
Cheers Glen, I have held off continuing ... More...






Comments
thx
Noxe
Having everything strongly typed in my opinion is something that should always tried to be acheived. Although I have never been a fan of "code generators" but I am starting to understand that there is a place in the world for them :)
Great post - as per usual! I also like to avoid the dreaded string literals in SetProperty, but use expressions to get the goodies out. Just posted my approach to the link below if you're interested.
Cheers
Sean
http://kearon.blogspot.com/2010/10/replacing-strings-in.html
Just read through your blog, very interesting alternative.
Pity it has the performance hit and introduces .NET 3 dependancy by using Lambda. But conceptually I would love to have a way to not have code generated. I suppose you could say that I love XPO_EasyFields as I haven't found an alternative. Your solution is getting closer, Reflection gives some great power but again it is all about "Searching" and using strings as indexes to bring up your members. I just wish MS would introduce some sort of "Class Extension" that would allow the usage of something like MyObject.ClassInfo.Property.Name but I won't hold my breath
So thanks for the comment and the link to the post, I've got a question about the implementation, might pop it on your blog
I couldn't find #PersistentProp ertySet# on my system, but altering #PersistentProp ertyBody# did the trick.
I use this setter for C#:
SetPropertyValu e(Fields.«Link(PropertyN ame)».PropertyName, ref «:#PropertyVar# », value);
Thanks
Fredrik
ahh, will have a look, I didn't think about it but my template is for VB.NET there would of course be a template for C# too, will double check your solution and update my post. Thanks for the heads up and glad I could help
As I mention in the third or so paragraph
"(The only place you can’t is in PersistentAlias attribute as .NET only allows constants and strings)"
I too liked the idea of using XPO_EasyFields for certain things. I made a "modification" to XPO_EasyField in which it also creates a Const for fields. These constants can be used in your attributes.
However the issue is you can't do nested constants :( so only fields with primitive types (String, Integer, Double, etc etc) can be used in this mannor.
I will attach the "beta" of the modification and see what your thoughts are.
I have uploaded a beta of an idea about generating Constants, you can download it here
www.alfware.com.au/component/content/article/1-blog/43-minor-update-to-xpoeasyfields-beta
Be interested to hear feedback on it.
RSS feed for comments to this post.