我试图找出一种方法来使用依赖注入与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中完成,如下所示:
<?xml version="1.0"?> <configuration> <system.web> <httpHandlers> <add verb="*" path="*.aspx" type="YourApp.CustomPageHandlerFactory,YourApp"/> </httpHandlers> </system.web> </configuration>
您的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)); } }
缺点是,这只有当你在完全信任运行你的一面。你可以阅读更多关于它here.但请注意,开发ASP.NET应用程序在部分信任seems a lost cause。