解析 ASP.NET Web 窗体图像控件派生 class 通过简单注入器注册
Resolving ASP.NET Web Forms Image Control derived class registered via 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)
{
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 注入到正确的位置,但我的 CustomImageControl 遇到了空引用。
这可以通过挂接到 Page
的 InitComplete
事件来完成。这是我用来证明这一点的代码。
我将 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 处更改。请务必在您的引导程序
中调用 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();
}
}
我要将存储库实例注入某些 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 注入到正确的位置,但我的 CustomImageControl 遇到了空引用。
这可以通过挂接到 Page
的 InitComplete
事件来完成。这是我用来证明这一点的代码。
我将 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 处更改。请务必在您的引导程序
中调用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();
}
}