我正試圖將依賴注入與Windsor連接到標準的asp.net web表單。我想我已經使用HttpModule和CustomAttribute(下面顯示的代碼)實現了這一點,儘管解決方案似乎有點笨拙,並且想知道Windsor是否有更好的受支持的解決方案?如何使用Castle Windsor與ASP.Net Web窗體?
有幾個文件都顯示一起在這裏
// index.aspx.cs
public partial class IndexPage : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
Logger.Write("page loading");
}
[Inject]
public ILogger Logger { get; set; }
}
// WindsorHttpModule.cs
public class WindsorHttpModule : IHttpModule
{
private HttpApplication _application;
private IoCProvider _iocProvider;
public void Init(HttpApplication context)
{
_application = context;
_iocProvider = context as IoCProvider;
if(_iocProvider == null)
{
throw new InvalidOperationException("Application must implement IoCProvider");
}
_application.PreRequestHandlerExecute += InitiateWindsor;
}
private void InitiateWindsor(object sender, System.EventArgs e)
{
Page currentPage = _application.Context.CurrentHandler as Page;
if(currentPage != null)
{
InjectPropertiesOn(currentPage);
currentPage.InitComplete += delegate { InjectUserControls(currentPage); };
}
}
private void InjectUserControls(Control parent)
{
if(parent.Controls != null)
{
foreach (Control control in parent.Controls)
{
if(control is UserControl)
{
InjectPropertiesOn(control);
}
InjectUserControls(control);
}
}
}
private void InjectPropertiesOn(object currentPage)
{
PropertyInfo[] properties = currentPage.GetType().GetProperties();
foreach(PropertyInfo property in properties)
{
object[] attributes = property.GetCustomAttributes(typeof (InjectAttribute), false);
if(attributes != null && attributes.Length > 0)
{
object valueToInject = _iocProvider.Container.Resolve(property.PropertyType);
property.SetValue(currentPage, valueToInject, null);
}
}
}
}
// Global.asax.cs
public class Global : System.Web.HttpApplication, IoCProvider
{
private IWindsorContainer _container;
public override void Init()
{
base.Init();
InitializeIoC();
}
private void InitializeIoC()
{
_container = new WindsorContainer();
_container.AddComponent<ILogger, Logger>();
}
public IWindsorContainer Container
{
get { return _container; }
}
}
public interface IoCProvider
{
IWindsorContainer Container { get; }
}
只想說感謝上面它讓我創造了一些傳統的web表單代碼的MVP框架的代碼。 – 2009-03-18 10:06:24
基思沒有問題..很高興它可能對某人有用 – Xian 2009-03-19 21:13:18
我試過這段代碼,但實際上每次請求都會清除ViewState。看起來,如果在Load事件之前訪問當前頁面的Controls屬性,則ASP.NET無法在Init和Load之間的LoadViewState階段恢復ViewState(請參閱forums.asp.net/p/1043999/1537884。 ASPX)。我相信這就是爲什麼Ayende分別在頁面,母版頁和用戶控件的基類中使用Init事件來解決任何IoC依賴性的原因。 – gabe 2009-09-28 18:57:13