我正试图将依赖注入与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