我试图将依赖注入与Windsor连接到标准的asp.net web表单。我想我已经实现了使用HttpModule和CustomAttribute(代码如下所示),虽然解决方案似乎有点笨重,并想知道是否有一个更好的支持解决方案开箱即用Windsor?
// 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; } }
解决方法
我想你基本上是在正确的轨道 – 如果你还没有建议看看Rhino Igloo,WebForms MVC框架,
Here’s a good blog post on this和来源是
here – Ayende(犀牛Igloo的作者)解决了问题在这个项目/库中使用Windsor与webforms相当好。
我将缓存反射信息,如果你要注入整个嵌套的控件,这可能最终是一个性能猪我怀疑。
最后,spring.net以更加面向配置的方式接近这一点,但是它可能值得看看它们的实现 – 这是一个很好的reference blog post。