Strongly Typed Column Specifications

Posted: 9/22/2020 10:54:29 AM by Chris Bass | with 0 comments
Filed under: API, Performance

I've been trying to find ways to make my Kentico coding be more reusable and future-proof lately, and one of the ways I've been doing that is by creating strongly-typed classes when I'm working with custom page types.

There's a lot that this gets you, like being able to extend the TreeNode and TreeNode Provider class (the generated classes are partials so you can create a secondary file to store the customizations). Primarily I've done this for transforms (say, first X characters of the description followed by '...'), data annotations, and custom retrieval scripts (I suppose this could also be in a Repository class, but the page types already come with a Provider class that has DocumentQuery expressions in it, so it seems to make sense to me to put other DocumentQuery expressions for the same type, in the same place. 

DocumentQuery is nice for a lot of things, but one area where it fails me is that in Where expressions, OrderBy expressions, and Columns specifications, you still have to say .WhereEquals("MyColumn", value)... thus coding in MyColumn as a string that isn't a compile-time error if the column name ever changes. It also means you can't trace the column through things like Find All References. Essentially, the problem in both cases is, you're hiding a dependency on that column name, by using it as a string.

It's up to you if you want to do it, but I think it has value in some cases. Now, Kentico really is expecting strings from it, but there's a few ways we can get it. Both revolve around the use of nameof(), for example, nameof(TreeNode.DocumentName) would return the string "DocumentName".

  1. We can just call nameof() directly in each class making Queries. This puts direct references to the fields in a lot of places, which means if it changes you're updating it in a lot of files.
  2. We can store the names right into the partial class itself, and just use nameof() directly in the getter for the name properties.
Sean Wright talks about the first option in his blog, a good read if you haven't seen it.

This second one is probably overkill, but if you're going to do it, I propose a class built into the (non-generated) partial class, called "Names". And then in that class, we simply have static properties that reference the names of any columns we care about. The benefit of this is, it puts all the nameof's in one place, but now of course you've got a secondary set of names and if the actual field name ever changes it's not going to make a whole lot of sense unless you rename your things anyways. 

On the other hand, doing a right-click rename on the Names fields you made is probably a lot simpler than remembering to right-click-rename the auto-generated field names *before* refreshing the file... it's a lot more likely you'll refresh the generated file and be like 'oh, this field changed, now there's errors everywhere' Having that initial error only happen in one place is arguably better than having it happen all over your site.

Do you just put string column names directly in your code, or do you do something like this? What's your preferred method? And have you ever had a situation like this where field names changed and you had to update them? Leave a comment and let me know!

Comments
Blog post currently doesn't have any comments.
 Security code