Estoy intentando conectar la inyección de dependencia con Windsor a los formularios web asp.net estándar. Creo que lo he logrado usando un HttpModule y un CustomAttribute (código que se muestra a continuación), aunque la solución parece un poco torpe y me preguntaba si hay una mejor solución compatible con Windsor.¿Cómo usar Castle Windsor con los formularios web ASP.Net?
hay varios archivos muestran todos juntos aquí
// 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; }
}
simplemente decir gracias por el código anterior, ya que me permitió crear un marco MVP por algún código de formularios web heredados. –
No hay problema Keith ...me alegro de que podría ser de alguna utilidad para alguien – Xian
probé este código, pero en realidad borra el ViewState en cada solicitud. Parece que si accede a la propiedad Controles de la página actual antes del evento Load, ASP.NET no puede restaurar ViewState durante la etapa LoadViewState entre Init y Load (consulte forums.asp.net/p/1043999/1537884. aspx). Creo que esta es la razón por la cual Ayende usa el evento Init en clases base para Página, MasterPage y UserControl, respectivamente, para resolver cualquier dependencia de IoC. – gabe