c# - 解析通过简单注入(inject)器注册的 ASP.NET Web 窗体图像控件派生类

标签 c# asp.net dependency-injection webforms simple-injector

我要将存储库实例注入(inject)到某些 Web.UI.WebControls.Image 派生类型中:

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}
    }
}

这也是我为测试目的而实现的默认页面:

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}
    }
}

我已经根据 official guide 实现了容器引导关于使用控制注册而不是页面:

    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;
    }

我完全从前面提到的指南中复制粘贴了 ControlInitializerModule、ImportAttributePropertySelectionBehavior 和 InitializeHandler 例程

在页面加载时,我最终得到了正确解析的默认页面实例,并将 CachedNameRepository 注入(inject)了正确的位置,但我的 CustomImageControl 遇到了空引用。

最佳答案

这可以通过挂接到 PageInitComplete 事件来完成。这是我用来证明这一点的代码。

我将 CustomImageControl 更改为继承自 UserControl:

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

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

这是更新后的 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);
        }
    }

以及文档中的其他 2 个更改。请务必在 Bootstrap 中调用 RegisterWebPagesAndControls

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();
    }
}

关于c# - 解析通过简单注入(inject)器注册的 ASP.NET Web 窗体图像控件派生类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29341192/

相关文章:

c# - win8 app中的流式布局容器

c# - 哪些程序集在 "found conflict between different versions"中发生冲突?

c# - 检查数据绑定(bind)是否存在

java - 如何动态确定运行时使用的服务类

c# - 在 Windows Phone 8 中解析 XML

javascript - asp.net-mvc ajax json post 到 Controller 操作方法

c# - 如何从网络服务返回响应

c# - 如何在 .NET Core 用户登录时创建目录

c# - 启动后向 IServiceCollection 注册类

symfony - FOSRestBundle Controller 作为服务无法正常工作