Before we can begin at looking at some code for creating server controls, I have added a few guidelines and trends for developing server controls. Note that I am not calling it rules; although I would like to. These are just some general guidelines and trends and I am not including every single one here because of the following reasons.
I am bound to forget to mention every single guideline or trend.
No one will remember all the rules for later on in the series.
I do not want to reference back to this article later in the series.
Without further a due, here is the general guidelines and trends:
The control class should be able to be inherited from
Whoever wants to extend your control, should be freely able to do so. No matter who your target audience is or what functionality and features that your control provides, you will always find that one developer who will want to extend it for his/her own extra mile.
The most common scenario is that the developer wants to create a control that they do not want to do common, repetitive data binding for every page. Sure they can drop your server control into a user control and do their data binding there and use that across their pages... but do you really want to do that if you spent an investment of your time for a rich design time (and possibly, to mention your customers investment of money into your product). If your “clients” really wanted to steal your control and publish it as their own, they would have to be forced to do one of the two things:
Attach your assembly to their distribution of their control (that is that their control cannot go solo without the help from your control).
Reverse engineer the byte-code that .NET Framework assemblies.
Other partial reasons are discussed below.
Rather override the appropriate methods than to attach to events when inheriting a control.
If you care about performance, this is one “rule” that you must keep in mind. Basically, you are saving extra memory being consumed which events point to delegated methods in your code. Obviously, you can avoid this by overriding the method name that is associated with the desired event – your code will then be inline with the execution of the event.
But most all, you might want to dominate how your code is going to run. You might want to do some processing before the actual event is fired or you might even want to dictate if the control fires its event at all. In other words, it puts you in the god role that you have absolute power. If you want the event to fire, ensure that its base's method that is associated with the event is called.
If you create custom events, create virtual (or overridable) methods to be associated with the events
On your quest around the .NET SDK, you might have noticed for every event, there is a method that is associated with that event, namely, OnEventName. You will also notice that the method's visibility is “protected”. The only reason why the accessor is protected is because it is not for use outside the control – instead, it should be used by controls that derive from it. Remember to mark it virtual, so the previous guideline “Rather override the appropriate methods than to attach to events when inheriting a control” can be obeyed by other control developers.
If overriding a method that is associated with an event, ensure that you call the base's method
This is not a hard-enforced rule as such but more of a fore-warning. If you want the event to be fired, then the base's method that is associated with the event must be called. The explanation is in both of the previously discussed guidelines and trends.
Always do your processing during the PreRender event of the page life cycle – not during the Load event.
This must be declared as a golden rule. The page developer do their processing during the Load event. You, as the control developer, is to take those changes that the page developer possibly did to your control during the Load event and start processing. To ensure that no “concurrency” error of order of events will occur, the last event that any major changes that can be done is during the PreRender event – straight after the Load event. It is just a precaution, just in case the page developer creates a page framework that may throw your processing off.
If you need to do some processing before the PreRender event, you can consider doing processing during the Init event.
Deliver data to view state and to persist during post backs
Pretty simple trend and should become a rule because so many control developers do not follow this. The usual excuse is that the page developer should not be lazy by setting those few properties or that the page developer should populate the data every time the page is executed. This just breaks the normal flow of developing pages and some might want to keep their 233MHz SQL Server machine a bit “airy” from unwanted requests. Although a database server is hardly found on a low resource as that, that might as well be the resources available if a web farm gets a sudden influx of traffic.
If you, as the control developer, insist that the page developer caches the DataTable, you might lose a valuable customer. The reason why you will lose him is because he will see your workmanship as lazy. Do not be a lazy developer yourself.
Expose Properties, not fields
There is one sole reason for doing this – keeping consistency with the current OOP model of the .NET Framework. It will also offer you more flexibility to do some changes between two versions of your controls without breaking them.
As I said before, we will analyse other guidelines and trends as we deal with the subject when we are examining it under great detail.