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

C# 解析通过简单注入器注册的ASP.NET Web窗体图像控件派生类,c#,asp.net,dependency-injection,webforms,simple-injector,C#,Asp.net,Dependency Injection,Webforms,Simple Injector,我将向某个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) {

我将向某个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}
    }
}
我已经根据使用控制注册而不是页面执行了容器引导:

    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;
    }
private void BootStrapContainer()
{
var container=新容器();
container.Options.PropertySelectionBehavior=新的ImportAttributePropertySelectionBehavior();
container.Register();
container.Register();//我也尝试过控件和图像类型
container.Register();
var cc=container.GetInstance();//在cc对象的Repo字段中正确实例化了CachedNameRepository实例
container.Verify();//此处为OK
Global.Container=Container;
}
我将ControlInitializerModule、ImportAttributePropertySelectionBehavior和InitializeHandler例程完全复制到前面提到的指南中


在页面加载时,我最终得到了正确解析的默认页面实例,其中CachedNameRepository被注入了正确的位置,但是我的CustomImageControl遇到了空引用。

这可以通过挂接
页面的
InitComplete
事件来实现。这是我用来证明这一点的代码

我将
CustomImageControl
更改为从
UserControl
继承:

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

    private void DynamicImage_PreRender(object sender, EventArgs e)
    {
    }
}
这是更新后的
初始化Handler

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);
        }
    }
以及文档中的另外两个更改。确保在引导程序中调用注册表WebPages和控件

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();
    }
}
专用静态无效注册表WebPagesAndControls(容器)
{
变量页面类型=
从BuildManager.GetReferencedAssemblys().Cast()中的程序集
哪里!assembly.IsDynamic
哪里!assembly.GlobalAssemblyCache
来自程序集中的类型。GetExportedTypes()
其中type.IsSubclassOf(typeof(Page))| | type.IsSubclassOf(typeof(UserControl))
其中!type.isastract&!type.IsGenericType
选择类型;
pageTypes.ToList().ForEach(container.Register);
}
类ImportAttributePropertySelectionBehavior:IPropertySelectionBehavior
{
public bool SelectProperty(类型serviceType,PropertyInfo PropertyInfo)
{
//使用System.ComponentModel.Composition程序集
return(typeof(Page).IsAssignableFrom(serviceType)||
typeof(UserControl).IsAssignableFrom(serviceType))&&
propertyInfo.GetCustomAttributes().Any();
}
}

如果在
public static void InitializeHandler(IHttpHandler handler)中添加断点
代码是否中断?@qujck execution不使用handler={ASP.default\u aspx}输入方法我猜没有为每个用户调用
PageInitializerModule
Control@qujck当我通过向CustomImageControl提供正确解析的ICachedNameRepository参数依赖项切换到构造函数注入时,但我不能继续使用该解决方案,因为ASP.NET需要用于web控件的无参数ctor。您的解决方案适合我。总而言之,这是关于您在InitializeHandler、InitiaizePage和InitiaizeControl部分中对registration.InitializeInstance方法所做的正确注册。我对这个想法的理解正确吗?@SergeyPrytkov;我还将
typeof(UserControl)
添加到
RegisterWebPagesAndControls
ImportAttributePropertySelectionBehavior
中,以便容器知道它们。我已经知道这些部分,正确的初始化对于我来说至关重要。谢谢你的帮助!