我试图找到一种方法来使用ASP.NET Web窗体控件的依赖注入.
我有很多控件可以直接创建存储库,并使用它们来访问和绑定数据等.
我正在寻找一种模式,我可以将存储库传递到外部控件(IoC),因此我的控件仍然不知道如何构建存储库以及它们来自何处等.
我不希望从我的控件中依赖IoC容器,因此我只希望能够使用构造函数或属性注入来构造控件.
(只是为了使事情复杂化,这些控件正在构建并在运行时由CMS放置在页面上!)
有什么想法吗?
您可以使用PageHandlerFactory
自定义构造函数注入替换默认值.这样,您可以使用重载的构造函数来加载依赖项.您的页面可能如下所示:
public partial class HomePage : System.Web.UI.Page { private readonly IDependency dependency; public HomePage(IDependency dependency) { this.dependency = dependency; } // Do note this protected ctor. You need it for this to work. protected HomePage () { } }
PageHandlerFactory
可以在web.config中配置该自定义,如下所示:
你CustomPageHandlerFactory
可以这样:
public class CustomPageHandlerFactory : PageHandlerFactory { private static object GetInstance(Type type) { // TODO: Get instance using your favorite DI library. // for instance using the Common Service Locator: return Microsoft.Practices.ServiceLocation .ServiceLocator.Current.GetInstance(type); } public override IHttpHandler GetHandler(HttpContext cxt, string type, string vPath, string path) { var page = base.GetHandler(cxt, type, vPath, path); if (page != null) { // Magic happens here ;-) InjectDependencies(page); } return page; } private static void InjectDependencies(object page) { Type pageType = page.GetType().BaseType; var ctor = GetInjectableCtor(pageType); if (ctor != null) { object[] arguments = ( from parameter in ctor.GetParameters() select GetInstance(parameter.ParameterType) .ToArray(); ctor.Invoke(page, arguments); } } private static ConstructorInfo GetInjectableCtor( Type type) { var overloadedPublicConstructors = ( from constructor in type.GetConstructors() where constructor.GetParameters().Length > 0 select constructor).ToArray(); if (overloadedPublicConstructors.Length == 0) { return null; } if (overloadedPublicConstructors.Length == 1) { return overloadedPublicConstructors[0]; } throw new Exception(string.Format( "The type {0} has multiple public " + "ctors and can't be initialized.", type)); } }
缺点是,这只适用于在Full Trust中运行您的一方.你可以在这里阅读更多相关信息.但请注意,部分信任开发ASP.NET应用程序似乎是一个失败的原因.
Autofac支持 ASP.NET WebForms中相当不引人注意的依赖注入.我的理解是它只是使用http模块挂钩到ASP.NET页面生命周期并进行属性注入.唯一的问题是,对于控件,我认为直到Init事件之后才会发生这种情况.