问题描述
我想与温莎线了依赖注入标准asp.net web表单。我想,我已经实现了这个使用的HttpModule和CustomAttribute(如下所示code)中,该解决方案似乎有点笨重,想知道是否有更好的解决方案,支持与走出温莎盒子?
的有如下所示在一起的几个文件中的所有
// index.aspx.cs
公共部分类IndexPage:System.Web.UI.Page
{
保护无效的Page_Load(对象发件人,EventArgs的发送)
{
Logger.Write(页面加载);
} [注入]
公共ILogger记录仪{搞定;组; }
} // WindsorHttpModule.cs
公共类WindsorHttpModule:IHttpModule的
{
私人HttpApplication的_Application;
私人IoCProvider _iocProvider; 公共无效初始化(HttpApplication的情况下)
{
_Application =背景;
_iocProvider =上下文IoCProvider; 如果(_iocProvider == NULL)
{
抛出新的InvalidOperationException异常(应用程序必须实现IoCProvider);
} _Application preRequestHandlerExecute + = InitiateWindsor。
} 私人无效InitiateWindsor(对象发件人,发送System.EventArgs)
{
当前是页= _application.Context.CurrentHandler的页面;
如果(当前是!= NULL)
{
InjectPropertiesOn(当前页);
currentPage.InitComplete + = {委托InjectUserControls(当前页); };
}
} 私人无效InjectUserControls(控制父)
{
如果(parent.Controls!= NULL)
{
的foreach(在parent.Controls控制控制)
{
如果(控制用户控件)
{
InjectPropertiesOn(对照组);
}
InjectUserControls(对照组);
}
}
} 私人无效InjectPropertiesOn(当前为对象)
{
的PropertyInfo []属性= currentPage.GetType()的GetProperties()。
的foreach(在性能的PropertyInfo财产)
{
[对象]属性= property.GetCustomAttributes(typeof运算(InjectAttribute),FALSE);
如果(属性=空&放大器;!&放大器; attributes.Length大于0)
{
反对valueToInject = _iocProvider.Container.Resolve(property.PropertyType);
property.SetValue(当前是,valueToInject,NULL);
}
}
}
} //的Global.asax.cs
公共类全球:System.Web.HttpApplication,IoCProvider
{
私人IWindsorContainer _container; 公共覆盖无效的init()
{
base.Init(); InitializeIoC();
} 私人无效InitializeIoC()
{
_container =新WindsorContainer();
_container.AddComponent< ILogger,记录仪>();
} 公共IWindsorContainer集装箱
{
{返回_container; }
}
} 公共接口IoCProvider
{
IWindsorContainer集装箱{搞定; }
}
我想你基本上是正确的轨道上 - 如果你还没有,我建议采取一看犀牛冰屋,一的WebForms MVC框架,Here's这个和源一个好的博客文章是。
I am trying to wire up dependency injection with Windsor to standard asp.net web forms. I think I have achieved this using a HttpModule and a CustomAttribute (code shown below), although the solution seems a little clunky and was wondering if there is a better supported solution out of the box with Windsor?
There are several files all shown together here
// 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; }
}
I think you're basically on the right track - If you have not already I would suggest taking a look at Rhino Igloo, an WebForms MVC framework, Here's a good blog post on this and the source is here - Ayende (the Author of Rhino Igloo) tackles the issue of using Windsor with webforms quite well in this project/library.
I would cache the reflection info if you're going to inject the entire nested set of controls, that could end up being a bit of a performance hog I suspect.
Last of all spring.net approaches this in a more configuration-oriented way, but it might be worth taking a look at their implementation - here's a good reference blog post on this.
这篇关于如何使用温莎城堡与ASP.Net Web窗体?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!