ASP.NET How-To: Create User Control library by compiling User Controls into .dll files

This blog post shows how to create a User Control library (a .dll file containing User Controls). To reuse the contained User Controls in other ASP.NET web projects you just need to add a reference to this .dll file and register a tag prefix (as shown at the end of this post).

First, we need the following base class for the User Controls that should be included in the library:

public abstract class UserControlBase : System.Web.UI.UserControl
{
  protected override void FrameworkInitialize()
  {
    base.FrameworkInitialize();
    string content;
 
    var resourceName = GetType().FullName + ".ascx";
    var stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(resourceName);
    if (stream == null)
    {
      throw new InvalidOperationException(
        string.Format("Loading resource '{0}' failed", resourceName)
      );
    }
 
    using (var reader = new StreamReader(stream))
    content = reader.ReadToEnd();
 
    var userControl = Page.ParseControl(content);
    if (userControl == null)
    {
      throw new InvalidOperationException(
        string.Format("Parsing user control in resource '{0}' failed", resourceName)
      );
    }
    Controls.Add(userControl);
 
    WireControls(userControl);
  }
 
  protected abstract void WireControls(System.Web.UI.Control userControl);
}

Next we remove the User Control’s designer file (the .ascx.designer.cs file) and remove all attributes except the Language attribute from the <Control> tag in the User Control’s .ascx file.

The exemplary User Control in this blog post contains a Literal control that shows the current time; the .ascx file looks as follows:

<%@ Control Language="C#" %>
 
<asp:Literal ID="Output" runat="server"></asp:Literal>

In the User Control’s code behind file we use the above defined UserControlBase class as parent class:

public partial class MyUserControl : UserControlBase
{
  private Literal output;
 
  protected void Page_Load(object sender, EventArgs e)
  {
    output.Text = DateTime.Now.ToString();
  }
 
  protected override void WireControls(System.Web.UI.Control userControl)
  {
    output = (Literal)userControl.FindControl("output");
  }
}

Please note: Since there is no designer file we need to create private fields for the controls and assign them manually by overriding the WireControls method of our UserControlBase parent class.

Before building the project to create the .dll library file we need to set the the build action for the .ascx to “Embedded Resource“.

You can download the Visual Studio 2010 project containing all the source code of the User Control library project here.

To include the User Control in any other ASP.NET project just add a reference to the (library) .dll file and add the User Control as follows on any ASP.NET page:

[...]
<%@ Register Assembly="UserControl-Dll-File" TagPrefix="uc" Namespace="UserControl_Dll_File" %>
<uc:MyUserControl ID="WebUserControl1" runat="server"></uc:MyUserControl>
[...]

Comments

  1. Lelala

    Hi,
    thanks for that post.
    But:
    How can you prevent the app from beeing restarted, if you replace that DLL file? If you do a copy-deploy, the app container is recycled?

  2. Jan Jonas

    Hi, that’s the normal behavior. If you replace a dll file in the bin folder or but a new dll file into that folder the app pool restarts to load the new assemblies.

  3. diegospc

    PERFECT!!! I’m new in ASP.NET and this is exactly that i was looking for.
    One question: I’m using AjaxControltoolkit in the control library and I try to use a FilteredTextbox control for filter TextBox input and limit it to only numbers. There are no error in compiling and execution time, but doesn’t work and I can write any character in the TextBox. There are something else that I must do?
    Thanks you a lot! and sorry if my english is bad, I’m learning it 🙂

  4. Chris

    This is superb. One question: Defining multiple user controls, how could I have multiple tag prefixes i.e:

    Many thanks for your great solution!

  5. Chris

    My previous comment removed the tags I used as an example so I’ll try it this way instead:

    <component:button></component:button>
    <layout:grid></layout:grid>

Leave a comment

Your email address will not be published. Required fields are marked *

*