I apologize if this is a little off-topic, but I know a few here have probably tackled this problem.
I am continuing to go into the process of code generation using partial classes with the codesmith templates for C#.
The trick with the usage of partial classes being the various hooks necessary to extend behavior of generated code - the current issue I'm running across is with the setting of properties - both prior to the value change and immediately afterwards.
One example of the prior to change is with, for instance, social security numbers - I want to allow various formats to be assigned to the social security number, but to have it automatically formatted to the proper format within the setter. Here, I'd want this to occur before _socialSecurityNumber = value.
An example of after the change is with name components. When a user has various name parts (first/last/middle/suffix/prefix), changes to these will affect the "derived names" (including a sort name). The user has the ability to modify this derived name and hence it has its own state in the object. So, after a name part is changed and for instance _lastName = value, I want to DeriveNames().
I considered including as meta-data of the objects (in the xml definition file) a includePropertyChanging and includePropertyChanged boolean flags, and when explicitly set to true I would include the necessary call to a specific and properly typed function for the handcrafted class to implement. Clearly, the class wouldn't compile with these functions not implemented, but I'd be explicitly saying that they will be implemented by utilizing the flags.
With respect to the property changing method, it would return a value of the same type and would cause the "value" in the setter to potentially change - that is - my SocialSecurityNumberPropertyChanging() would end up returning the properly formatted value, and assignment would occur to the formatted value.
I'm sure at a minimum this gets my general problem across... I could also have a single "PropertyChanging()" and "PropertyChanged()" method (not strongly typed and using a switch statement).
Appreciate any advice - thanks!
You could also use private events for this purpose. In VB this is an excellent option, because you can use WithEvents/Handles to automantically hook the events - meaning in the user code the only code required are the event handlers. In C# this isn't as nice, but is still workable, and is why I added the Initialize() method to all the base classes (so you can insert the event hookup code).
Another option is to end up with THREE classes (two genned, one user):
CustomerBase.xx (genned)
Customer.genned.xx (genned)
Customer.xx (user)
In CustomerBase you would define protected virtual/Overridable methods for all your pre/post get/set scenarios. Then in Customer.genned your property implementations would invoke those methods - which would always work, but would do nothing. Then the developer could override them in Customer on an as-needed basis.
I like this option because it avoids the overhead of events, and allows the user code to only implement methods they care about with no extra work - even in C# - so the user code is very focused. It is also strongly typed.
The only drawback is that you need to code-gen the base class as well as the partial class, so it is like a combination of the standard inheritance technique with the new partial class technique.
But if you think about why partial classes work so well for Windows Forms and Web Forms, it is not in small part because Microsoft's base classes (Form and Page) provide useful hooks. On the other hand, it is also the case that partial classes were designed for event-driven scenarios, with the basic assumption being that the user code could just handle a set of events to do its work...
I think the route Andres is suggesting is a nice simple approach that gets me through everything I need to worry about at this point. Your post, Rocky, is useful in thinking about future hooks that may need to be added to accomodate more flexibility.
Good replies both, thank you.
Chris
Chris,
When creating the partial class, I was debating whether I need to add hooks before and after value assignment in property set.
I figured that hook after value assignment is not needed since you can either override the OnPropertyChanged (just like Andres has shown) or override PropertyHasChanged if you need to inject the code before validation take place.
I ended up not implementing hook before value assignment. The only time I see this is needed when you need to add code that need to use the original value. In my experience this is rarely happening, and by not adding this hook I could make the code less complex and possibly (yet to test) avoid performance issue.
Of course, somebody might experience this differently. If you do, I would like to hear your experience.
Ricky
Ricky,
As I took Andres suggestion to override OnPropertyChanged and I went through and implemented my handcrafted pieces, I found no requirements that necessitated an extra hook before the property changed (like you say, the only reason is to need to know what the original value is).
That's not to say that perhaps there won't be a case like that, but since I didn't encounter one I didn't want to pursue it.
Thanks for your input
Chris
Copyright (c) Marimer LLC