Ensuring a Single Instance of a Control on a Page

An entry about asp.net Publication date 13. April 2007 22:26

Sometimes, ensuring that there exists one and only one instance of a Control on any given Page may be a good idea. A great example of this is the WebPartManager control that you need to place on any page that uses WebParts - or the ScriptManager control that you need in order to use ASP.NET Ajax. Omit them and you'll get an exception stating that its missing - add more than one and you'll get an exception saying that you can only have one.

If you've ever wondered how to implement such a control, here's an example - which is essentially similar to how the WebPart and ScriptManagers are implemented:

public class MyManager : Control
{
protected override void OnInit(EventArgs e)
{
base.OnInit(e);
Page page = this.Page;
if (page != null)
{
// check if an instance has already been added to the page
            if (page.Items.Contains(typeof(MyManager)))
{
throw new InvalidOperationException("Only one instance of the MyManager control can be placed on a Page");
}
// add a reference to the Items collection for easy reference to the control; GetCurrent() will use this
            page.Items[typeof(MyManager)] = this;
}
}
/// <summary>
    /// Gets the current MyManger instance on a given Page
    /// </summary>
    /// <param name="page">The page</param>
    /// <returns>The MyManager control</returns>
    /// <exception cref="InvalidOperationException">If no MyManager control exists on the page</exception>
    public static MyManager GetCurrent(Page page)
{
if (null == page)
{
throw new ArgumentNullException("page");
}
// get the manager - remember we added it to the Items collection in OnInit
        MyManager manager = page.Items[typeof(MyManager)] as MyManager;
if (null == manager)
{
// no manager on Page - crash and burn
            throw new InvalidOperationException("Could not find a MyManager control on the page");
}
return manager;
}
}

Implemented like this, the first MyManager control that gets added to a page stores a refrence to itself in the page context. The page context (the Page.Items property) is basically an IDictionary that has the same lifetime as the page, so its ideal for storing things that you'll need later on in the page life cycle. Once the first control has been added, any subsequent controls that tries to add itself will throw an exception alerting the user that this is not allowed.

Now, when we need to get at the current MyManger control on a page, we can do so at any time in the page lifetime after the Init stage using the static GetCurrent method. In the above implementation this will throw an exception if the control has not been added - wheter you want to do this instead of just returning null depends on how you intend to use the control.

Currently rated 3.5 by 2 people

  • Currently 3.5/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Comments

Powered by BlogEngine.NET 1.4.5.0

Welcome!

My name is Fredrik Kalseth, and this is my blog - thanks for visiting! I am fortunate enough to work with what I love for a living, and this blog is essentially the biproduct of that.

I work as a senior consultant for Capgemini, and am also an active participant in the Norwegian .NET community, as an avid attendee but also as a speaker (most recently at NNUG and MSDN Live).

As a developer, I have a wide circle of interest. My primary passion is for agile, test-driven development, with focus on best practices and clean code. That said, I also love to work on the frontend, especially with web development.

On Twitter? My handle is fkalseth. On LinkedIn? I`m there too.


Disclaimer

This is a personal blog; any opinions expressed here are my own and do not necessarily reflect those of my employer. All content herein is my own original creation, and as such is protected by copyright law. Unless otherwise stated, all source code posted on this blog is freely usable under the Microsoft Permissive License.

What Readers Talk About

Comment RSS