Oct
04
2010

XPO_EasyFields and SetPropertyValue

User Rating: / 0
PoorBest 

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) :(

  1. Use it for DataBinding via Code where I specify the DataMember by using
  2. Use it for FieldName property of your GridColumn
  3. Use it to add properties to your XPView
  4. Use it when creating your Criteria
  5. Use it to build a “Add Field” menu for a selection of Fields to get from the Database
  6. 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

  1. Open up your CodeRush options CTRL+SHIFT+ALT+O
  2. Open  Editor > Templates
  3. Search for #per
  4. Select the DevEx > XPO > System >
    VB.NET
    #PersistentPropertySet# item
    C#
    #PersistentPropertyBody# item
  5. 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);
  6. 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

Comments  

 
0 # 2010-10-04 17:47
Great Post Michael!!

thx
Noxe
Reply | Reply with quote | Quote
 
 
0 # Michael Proctor [Dx-Squad] 2010-10-04 22:00
Cheers dude, appreciate the comment, it is something I think is critical especially in OO programming.

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 :)
Reply | Reply with quote | Quote
 
 
0 # 2010-10-05 04:50
Hi Michael

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
Reply | Reply with quote | Quote
 
 
0 # Michael Proctor [Dx-Squad] 2010-10-05 07:05
Hi Sean,
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
Reply | Reply with quote | Quote
 
 
0 # 2010-10-05 17:20
Great post!

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
Reply | Reply with quote | Quote
 
 
0 # Michael Proctor [Dx-Squad] 2010-10-05 21:14
Hi 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
Reply | Reply with quote | Quote
 
 
+1 # Michael Proctor [Dx-Squad] 2010-10-05 21:24
Thanks mate, just confirmed that indeed there is different template for each language (well duh of course there would be), just hadn't thought about it, so thanks again for the heads up.
Reply | Reply with quote | Quote
 
 
0 # 2010-10-11 21:10
I would like to use XPO_EasyFields with the System.ComponentModel.DefaultProperty Attribute, instead of string representations . Can I?
Reply | Reply with quote | Quote
 
 
+1 # Michael Proctor [Dx-Squad] 2010-10-12 08:11
Funny you should ask... ;)

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.
Reply | Reply with quote | Quote
 
 
0 # Michael Proctor [Dx-Squad] 2010-10-12 08:53
Hi Fredrik,
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.
Reply | Reply with quote | Quote
 

Add comment

Although I believe your free to say what you want, please don't abuse either myself or other peoples, be constructive.


Security code
Refresh

Latest Comments

My Twitter

Follow me on twitter