User controls are great. They allow a developer to encapsulate functionality that can be reused throughout applications. Like any well designed class, they allow the consumer to care only about the interface and not inner workings. And from a team perspective, they provide logical separation of tasks so that multiple developers can work on related functionality simultaneously.
But just like everything else in this world, there can always be too much of a good thing.
Too many user controls can be a pain to manage, add overhead, and potentially make the data youre trying to work with harder to retrieve. Plus, building new controls does come with a cost and you dont want to waste your time. Below are some questions I think you should ask yourself before deciding to build a user control. Specifically Im thinking in the context of ASP.NET web development, but much of this relates to Winform and development, too.
Does my control have a unique behavior?
Its easy to fall into the trap of data (not behavior) dictating the need for a user control. Lets say that a couple web pages need to allow users to select from a list of apples. Before you know it, someone builds ApplePicker. The ApplePicker usercontrol contains a DropDownList control and allows the consumer to set the data source to a list through a DataSource property. Andand thats about all.
It turns out there is no behavioral difference between the two controls. The task of showing selectable lists of fruit could easily be achieved by simply using a DropDownList control itself. Now if the ApplePicker provided a list of options AND conditionally showed an icon based on whether the selected Apple is good for making pies or just good for snacking, then youve probably defined some unique behavior. In this case a custom user control is probably in order.
What if I just used a utility/helper class instead?
So lets suppose the ApplePicker user control was simply a DropDownList as we initially discussed. But now the control is going to be "data aware". It knows how to load itself full of Apples. While its pretty cool to be able to drop a control on a page and "it just works" by filling its data source, in my Ive found that it tends to not be all that practical or even all that beneficial. The rationale behind such a design decision is usually to avoid having to wire up the data source of your control on every web page and allow for ease updating the actual data source. These goals can be achieved in a better way.
Defining a static method a utility or helper class (Utility.GetApples()) allows for a consistent way to load the ApplePicker on all your web pages. The actual source of data can be changed for all controls by changing the inner workings of the GetApples method. And it also allows you to change the data source in any exception cases. For example, most web pages may show a full list of apples, but one may need to show a list of Favorite Apples that a user has defined. Both lists can be displayed with a single control that is now more in tune with a Model View Controller pattern. This can also help you consistently add the typical "-- Please Pick An Apple --" or blank first item in your list. I really like following this kind of pattern with controls to separate the behavior and display and find that it is almost always beneficial.
Do I need to lock down access to my functionality?
So lets suppose the ApplePicker user control was simply a DropDownList as we initially discussed. What if I want to lock down the way consumers use my control. For example, I feel strongly that consumers should only pass in a List<Apple> (List(Of Apples) in VB) then maybe Id want my own strongly typed DataSource property. A better rationale, though, would be that certain methods or properties of the standard control provide more access than you want consumers to have. For example, you may wish to only allow the Text property to be read-only. Access alone is probably not going to justify use of a user control since in most cases youll probably want to lock down access to something that relates to unique behavior.
Am I just trying to prevent duplication of code?
Ill buy code reuse as justification for a user control. But only if there is a lot. If you have two web pages that have to show a list of Apples and the list can simply be achieved with the afore mentioned DropDownList, youre not going to win me over. If you have 20 web pages that need to display this list of Apples with a red Font and green BackColor, then youre getting warmer. But Id probably look to see what we could achieve using skins and themes instead. In general, I think you should try to avoid the "duplication of code" argument unless you have a composite UI (multiple controls) like the conditional icon example.
Should I build a templated control?
Lastly, returning to the MVC and "behavior" theme, I think its good to ask whether templated controls are a good fit for your design. Youve defined a unique behavior, but it before you know it, some web page may require 90% of the functionality in your user control, but they want to make a subtle UI change. For example, instead of a conditional icon indicating the best use of the selected apple, you may just want to display the text "Pie" or "Snack." ASP.NET offers some cool functionality allowing you to define a control that allows the UI to be tweaked via templates. This certainly involves more work when building your control, but it may be a good way for you to extend the reuse of your control.
Summary
Im a big fan of user controls, and an even bigger fan when they are thoughtfully designed and reusable. As discussed above, there are plenty of great reasons to use them. However, they can become maintenance nightmare and simply add to overhead. I know this topic can spark a lot of opinion and debate, but hopefully these questions will help you make future decisions about when to create user controls your applications.
Share this post: Email it! | bookmark it! | digg it! | reddit!