简体   繁体   中英

Resolving ASP.NET Web Forms Image Control derived class registered via Simple Injector

I'm about to inject a repository instance into some Web.UI.WebControls.Image derived type:

public class CustomImageControl : Image
{
    [Import]
    public ICachedNameRepository Repo { get; set; } // Null reference here

    private void DynamicImage_PreRender(object sender, EventArgs e)
    {
        ImageUrl = {some ICachedNameRepository usage}
    }
}

Also here is my default page I have implemented for testing purposes:

public partial class _Default : Page
{
    [Import]
    public ICachedNameRepository Repo { get; set; } // Totally ok here

    protected void Page_Load(object sender, EventArgs e)
    {
        {some ICachedNameRepository usage}
    }
}

I have implemented container bootstraping according to official guide with respect of usage Control registering instead of Page:

    private void BootStrapContainer()
    {
        var container = new Container();
        container.Options.PropertySelectionBehavior = new ImportAttributePropertySelectionBehavior();            

        container.Register<ICachedNameRepository, CachedNameRepository>();
        container.Register<CustomImageControl>(); // Also I have tried Control and Image types
        container.Register<Page>();
        var cc = container.GetInstance<CustomImageControl>(); // Correctly instantiated CachedNameRepository instance in Repo field in cc object

        container.Verify(); // OK here
        Global.Container = container;
    }

I left ControlInitializerModule, ImportAttributePropertySelectionBehavior and InitializeHandler routines completely copypasted from guide mentioned earlier

At page loading I ended up with correctly resolved default page instance with CachedNameRepository injected into the right place, but my CustomImageControl suffering from null reference.

This can be done by hooking into the InitComplete event of the Page . This is the code I've used to prove this.

I changed CustomImageControl to inherit from UserControl :

public partial class CustomImageControl : UserControl
{
    [Import]
    public ICachedNameRepository Repo { get; set; }

    private void DynamicImage_PreRender(object sender, EventArgs e)
    {
    }
}

Here's the updated InitializeHandler

public class Global : HttpApplication
{
    private static Container container;

    public static void InitializeHandler(IHttpHandler handler)
    {
        if (handler is Page)
        {
            Global.InitializePage((Page)handler);
        }
    }

    private static void InitializePage(Page page)
    {
        container.GetRegistration(page.GetType(), true).Registration
            .InitializeInstance(page);

        page.InitComplete += delegate { Global.InitializeControl(page); };
    }

    private static void InitializeControl(Control control)
    {
        if (control is UserControl)
        {
            container.GetRegistration(control.GetType(), true).Registration
                .InitializeInstance(control);
        }
        foreach (Control child in control.Controls)
        {
            Global.InitializeControl(child);
        }
    }

And the 2 other changes from the documentation. Be sure to call RegisterWebPagesAndControls in your bootstrapper

private static void RegisterWebPagesAndControls(Container container)
{
    var pageTypes =
        from assembly in BuildManager.GetReferencedAssemblies().Cast<Assembly>()
        where !assembly.IsDynamic
        where !assembly.GlobalAssemblyCache
        from type in assembly.GetExportedTypes()
        where type.IsSubclassOf(typeof(Page)) || type.IsSubclassOf(typeof(UserControl))
        where !type.IsAbstract && !type.IsGenericType
        select type;

    pageTypes.ToList().ForEach(container.Register);
}

class ImportAttributePropertySelectionBehavior : IPropertySelectionBehavior
{
    public bool SelectProperty(Type serviceType, PropertyInfo propertyInfo)
    {
        // Makes use of the System.ComponentModel.Composition assembly
        return (typeof(Page).IsAssignableFrom(serviceType) ||
            typeof(UserControl).IsAssignableFrom(serviceType)) &&
            propertyInfo.GetCustomAttributes<ImportAttribute>().Any();
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM