我正在尝试使用IoC加载web用户控件。我用的是统一性,我按照书中的例子来设置。到目前为止,还不错,但是当我注入外观单个控件本身的接口时,我遇到了一个问题。我试图使用LoadControl(类型、参数),但是没有加载web用户控件。
我环顾网络,找不到任何东西来帮助我使用IoC动态加载web用户控件。
你们中有谁有其他策略来装载它吗?你需要更多关于我的尝试的信息吗?
问候
发布于 2014-06-13 21:55:00
让您的DI容器连接您的页面、HttpHandler和UserControls是绝对有可能的,但是没有任何内置的东西,所以您必须自己做。有两种方法可以做到这一点。您可以创建自定义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中。它甚至链接到控件层次结构中任何DataBound的DataBoundControl事件,以确保由DataBoundControl加载的任何UserControl都被初始化。
我认为这应该是个好办法:-)
https://stackoverflow.com/questions/24209905
复制相似问题