2010-12-16 41 views
3

我有一個aspx頁面,我想注入一個用戶控件的引用。用戶控件存儲在單獨的程序集中並在運行時加載。在注入用戶控件之後,它應該被加載到頁面的控件集合中。在WebForms中注入一個Web用戶控件與Ninject

一切似乎正常工作期望的點添加到頁面的控制。沒有錯誤,但控件的用戶界面不顯示。

的global.asax.cs

protected override Ninject.IKernel CreateKernel() 
{ 
    var modules = new INinjectModule[] { new MyDefaultModule() }; 
    var kernel = new StandardKernel(modules); 

    // Loads the module from an assembly in the Bin 
    kernel.Load("ExternalAssembly.dll"); 
    return kernel; 
} 

,這裏是外部模塊是如何在其他組件中定義:

public class ExternalModule : NinjectModule 
{ 
    public ExternalModule() { } 
    public override void Load() 
    { 
     Bind<IView>().To<controls_MyCustomUserControlView>(); 
    } 
} 

調試器顯示,當應用程序運行時,負載上外部模塊正在被調用,並且依賴被注入到頁面中。

public partial class admin_MainPage : PageBase 
{ 
    [Inject] 
    public IView Views { get; set; } 

在這一點上,當試圖添加視圖(這裏是一個用戶控件)到頁面,沒有任何顯示。這是否與用戶控件由Ninject創建的方式有關?加載的控件似乎有一個空的控件集合。

aspx頁面內

var c = (UserControl)Views; 

// this won't show anything. even the Control collection of the loaded control (c.Controls) is empty 
var view = MultiView1.GetActiveView().Controls.Add(c); 

// but this works fine 
MultiView1.GetActiveView().Controls.Add(new Label() { Text = "Nice view you got here..." }); 

終於視圖/用戶控件:

public partial class controls_MyCustomUserControlView : UserControl, IView 
{ 
} 

它僅包含一個標籤:

<%@ Control Language="C#" AutoEventWireup="true" CodeFile="MyCustomUserControlView.ascx.cs" Inherits="controls_MyCustomUserControlView" %> 

<asp:Label Text="Wow, what a view!" runat="server" /> 
+0

之前有人建議MEF或System.Addin,我已經嘗試過它們。 – yanta 2010-12-16 17:35:29

回答

2

通過調用之所以能得到這個工作將用戶控件作爲資源的Page.LoadControl。 Page.LoadControl(typeof(controls_controls_MyCustomUserControlView),null)不起作用,但是Page.LoadControl(「controls_MyCustomUserControlView.ascx」)的確如此。

由於控制是在外部裝配,首先創建一個的VirtualPathProvider和VirtualFile所討論http://www.codeproject.com/KB/aspnet/ASP2UserControlLibrary.aspx

定製的VirtualPathProvider將用於檢查用戶是否控制位於一個外部組件,並且VirtualFile(用戶控制)將從程序集中作爲資源返回。

接着設置的Ninject模塊加載用戶控制:

public override void Load() 
    { 
     //Bind<IView>().To<controls_MyCustomUserControlView>(); 
     Bind<IView>().ToMethod(LoadControl).InRequestScope(); 
    } 

    protected IView LoadControl(Ninject.Activation.IContext context) 
    { 
     var page = HttpContext.Current.Handler as System.Web.UI.Page; 
     if (page != null) 
     { 
      //var control = page.LoadControl(typeof(controls_MyCustomUserControlView), null); 
      var control = page.LoadControl("~/Plugins/ExternalAssembly.dll/MyCustomUserControlView.ascx"); 
      return (IView)control; 
     } 
     return null; 
    } 

「插件」是剛好在的VirtualPathProvider確定所述控制位於另一組件的前綴。

如果您的用戶控件有一個名稱空間,那麼請確保在LoadControl中將控件名稱作爲前綴。另一件事是確保使用CodeBehind代替CodeFile,因爲ASP.NET會嘗試加載CodeBehind文件。

<%@ Control Language="C#" AutoEventWireup="true" 
CodeBehind="~/MyCustomUserControlView.ascx.cs" Inherits="controls_MyCustomUserControlView" %>