Loading embedded UserControls from assemblies

By | August 27, 2010

I needed a way to share custom UserControls between different projects. There are a lot of articles about this already on the web, but it did take me a little while to pick a suitable approach and work it out. I eventually settled for creating a VirtualPathProvider and embedding my UserControls in the assembly of a separate web application. The inspiration came from this article on codeproject.

It really works like a charm, but I didn’t like the way how the LoadControl() gets called. From my point of view it felt a little unnatural to remember the specific way to build the virtual path to load the assembly. I wrapped this in a little extension method on the Page class. It’s just a little wrapper to provide a clearer call to LoadControl().

public static class PageExtensions
{
    public static Control LoadControl(this Page page, string assemblyName,
        string namespaceName, string userControlName)
    {
        try
        {
            string virtualPath = String.Format("~/App_Resource/{0}/{1}.{2}",
                assemblyName, namespaceName, userControlName);

            return page.LoadControl(virtualPath);
        }
        catch (Exception ex)
        {
            throw new Exception("Loading embedded user control failed! "
                + "See InnerException for more details.", ex);
        }
    }
}

This way, whenever I need to load a UserControl that has been embedded in an assembly, I can simply call the overloaded LoadControl() method without having to remember the precise syntax of the URL. For example:

protected void Page_Load(object sender, EventArgs e)
{
    Control myCustomCtrl = LoadControl(
        "Storminajar.MyWeb.UserControls.dll",
        "Storminajar.MyWeb.UserControls",
        "CustomControl.ascx");

    // Add control to the page.
    this.PlaceHolder1.Controls.Add(myCustomCtrl);
}

The good part about this is that I can still cast the Control to a real CustomControl object and set additional properties if I want to. Remember when doing this, a reference needs to be made to the Storminajar.MyWeb.UserControls.dll assembly! The reference isn’t strictly necessary when just loading a UserControl without the need to access specific properties.

Also, an interesting  thing I found out is that I can only seem to load this control through the code-behind. When I declare the control in my aspx file, it doesn’t seem to want to instantiate the controls (such as combo boxes, grids, etc). So, for example, the following code does not work:

<%@ Page Language="C#" AutoEventWireup="true"
    CodeBehind="Default.aspx.cs" Inherits="Storminajar.MyWeb.Default"
    MasterPageFile="~/Shared/Templates/Site.Master"
    Title="Default page illustrating my example." %>

<%@ Register Assembly="Storminajar.MyWeb.UserControls"
    Namespace="Storminajar.MyWeb.UserControls" tagPrefix="Library" %>

Nor does the following work:

<%@ Page Language="C#" AutoEventWireup="true"
    CodeBehind="Default.aspx.cs" Inherits="Storminajar.MyWeb.Default"
    MasterPageFile="~/Shared/Templates/Site.Master"
    Title="Default page illustrating my example." %>

<%@ Register tagPrefix="Library" tagName="CustomControl"
    Src="~/App_Resource/Storminajar.MyWeb.UserControls.dll/
           Storminajar.MyWeb.UserControls.CustomControl.ascx"
%>

I can’t for the life of me imagine why this wouldn’t instantiate all the different components in the UserControl; especially Telerik components, such as: RadComboBox, RadGrid, etc. If anyone spots the errors (ignore the capitalisation issues in my sample, for some reason I can’t get the text formatted properly), I would appreciate it if you let me know!


Leave Your Comment

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

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>