[英]ASP.NET WebForms dynamic load WebUserControls using IoC
我正在嘗試使用IoC加載Web用戶控件。 我正在使用統一,我按照書中的例子設置。 到目前為止一切都那么好,但是當我注入看起來單獨控件本身的界面時,我遇到了問題。 我正在嘗試使用LoadControl(類型,參數),但未加載Web用戶控件。
我環顧網絡,找不到任何東西來幫助我使用IoC動態加載Web用戶控件。
你們中的任何人都有其他加載策略嗎? 您是否需要有關我的嘗試的更多信息?
問候
讓你的DI容器連接你的Page,HttpHandler和UserControls絕對可以使用Web Forms,但是沒有內置任何東西,所以你必須自己做。 有兩種方法可以做到這一點。 您可以創建自定義PageHandlerFactory
也可以創建自定義HttpModule
。 由於掛鈎PageHandlerFactory
的唯一方法是通過web.config,我的偏好是使用HttpModule
。 使用HttpModule
,可以使用System.Web.PreApplicationStartMethodAttribute
(System.Web程序集)和Microsoft.Web.Infrastructure.DynamicModuleHelper.DynamicModuleUtility
(Microsoft.Web.Infrastructure程序集)注冊它。 這看起來像這樣:
[assembly: System.Web.PreApplicationStartMethod(typeof(ModuleInitializer), "Init")]
public static class ModuleInitializer
{
public static void Init()
{
DynamicModuleUtility.RegisterModule(
typeof(WebFormsDependencyInjectionHttpModule));
}
}
使用自定義HttpModule
的技巧是掛鈎應用程序的PreRequestHandlerExecute
事件。 這允許您在頁面執行之前瀏覽頁面層次結構並注入任何依賴項。
public class WebFormsDependencyInjectionHttpModule : IHttpModule {
public static UnityContainer Container;
private HttpApplication application;
public void Init(HttpApplication context) {
this.application = context;
context.PreRequestHandlerExecute += this.PreRequestHandlerExecute;
}
public void Dispose() { }
internal static void InitializeInstance(object instance) {
Container.BuildUp(instance);
}
private void PreRequestHandlerExecute(object sender, EventArgs e) {
if (Container == null)
throw new InvalidOperationException("Set Container first.");
var handler = this.application.Context.CurrentHandler;
if (handler != null) {
InitializeHttpHandler(handler);
}
}
private void InitializeHttpHandler(IHttpHandler handler) {
InitializeInstance(handler);
if (handler is Page) {
PageInitializer.HookEventsForUserControlInitialization((Page)handler);
}
}
private sealed class PageInitializer { ... }
}
這個模塊只是確保在頁面生活方式的早期調用Unity的BuildUp
方法來構建Page
或IHttpHandler
實例。 這允許您將依賴項注入到Page類中,但不會在任何使用過的UserControl
實例中注入任何依賴項。 要啟用此功能,模塊將調用特殊的PageInitializer.HookEventsForUserControlInitialization
方法。 這里的PageInitializer
類是:
internal sealed class PageInitializer {
private HashSet<Control> alreadyInitializedControls = new HashSet<Control>();
private Page page;
internal PageInitializer(Page page) {
this.page = page;
}
internal static void HookEventsForUserControlInitialization(Page page) {
var initializer = new PageInitializer(page);
page.PreInit += initializer.PreInit;
page.PreLoad += initializer.PreLoad;
}
private void PreInit(object sender, EventArgs e) {
this.RecursivelyInitializeMasterPages();
}
private void RecursivelyInitializeMasterPages() {
foreach (var masterPage in this.GetMasterPages())
this.InitializeUserControl(masterPage);
}
private IEnumerable<MasterPage> GetMasterPages() {
MasterPage master = this.page.Master;
while (master != null) {
yield return master;
master = master.Master;
}
}
private void PreLoad(object sender, EventArgs e) {
this.InitializeControlHierarchy(this.page);
}
private void InitializeControlHierarchy(Control control) {
var dataBoundControl = control as DataBoundControl;
if (dataBoundControl != null) {
dataBoundControl.DataBound += this.InitializeDataBoundControl;
} else {
var userControl = control as UserControl;
if (userControl != null)
this.InitializeUserControl(userControl);
foreach (var childControl in control.Controls.Cast<Control>()) {
this.InitializeControlHierarchy(childControl);
}
}
}
private void InitializeDataBoundControl(object sender, EventArgs e) {
var control = (DataBoundControl)sender;
if (control != null) {
control.DataBound -= this.InitializeDataBoundControl;
this.InitializeControlHierarchy(control);
}
}
private void InitializeUserControl(UserControl instance)
{
if (!this.alreadyInitializedControls.Contains(instance)) {
WebFormsDependencyInjectionHttpModule.InitializeInstance(instance);
// Ensure every user control is only initialized once.
this.alreadyInitializedControls.Add(instance);
}
}
}
該PageInitializer
類將采取工藝更進了一步,將鈎掛在頁面的PreInit
和PreLoad
的事件,讓依賴注入到母版頁和經過完全控制層次結構,以依賴注入任何UserControl
。 它甚至掛鈎到控件層次結構中任何DataBoundControl
的DataBound
事件,以確保DataBoundControl
加載的任何UserControl
都被初始化。
我認為這應該做的伎倆:-)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.