微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

为什么每个人都在ASP.NET Webforms中依赖注入是困难的,当PageHandlerFactory和IHttpHandlerFactory存在时?

所以我有一个遗留的webforms网站,正在努力使它更容易维护.把它拿走并重写它不是一个选择.

IoC显然是它得到的第一件事情,但这给我留下了服务定位模式和不好的味道,以及是否可以做得更好.

我已经在线聊天的各位告诉我,我可以使用一个HttpModule进行属性注入,该模式可以扫描一个用类别为Inject属性装饰的属性页面类,但这听起来像是一个Reflection(缓存,但仍然)每一个请求不吸引人

所以我正在看其他的选择,并发现了System.Web.IHttpHandlerFactory,这显然是从v2以来的框架.可以在httpHandlers web.config部分中删除认的* .aspx处理程序并将其替换为使用自定义实现的处理程序.

所以,我谈过的人并不愚蠢;我以为我会问这里.是否有任何问题,用基于IoC的实现替换Webforms PageHandlerFactory??

看起来它有一个CreateHandler和ReleaseHandler方法,所以生活方式相关的内存从容器泄漏,保留对创建的组件的引用不应该是一个问题…

解决方法

由于ASP.NET的设计方式,页面类需要有一个认构造函数.当你想使用构造函数注入时,有一个办法.您可以使认构造函数受保护,并添加单个公共构造函数,该构造函数采用依赖关系,如下所示:
public partial class _Default : System.Web.UI.Page
{
    private IUserService service;

    protected _Default()
    {
    }

    public _Default(IUserService service)
    {
        this.service = service;
    }
}

这允许您创建一个自定义的PageHandlerFactory并在构造函数中注入依赖关系.

所以这是有效的,但有一个抓住.您定义的_Default类不是ASP.NET使用的实际类. ASP.NET创建一个继承自_Default的新类.这个新类基于.aspx文件中的标记构建一个控制层次结构.这个班看起来有点像这样:

public class ASPGeneratedDefault : _Default
{
    public ASPGeneratedDefault() : base()
    {
    }

     protected override void OnPreInit(object s,EventArgs e)
     {
          // Building up control hierarchy.
     }
}

如您所见,ASP.NET中的自定义构造函数尚未被ASPGeneratedDefault覆盖.因此,没有办法让DI框架为我们创建这种类型.这样做的方法是让ASP.NET为我们创建此类型,并调用该现有实例上_Default基类的非认构造函数.因为这个实例已经存在,所以我们必须用反射来做到这一点,而当以部分信任运行时,这将失败.

此外,这适用于页面类,但不适用于页面上的用户控件. ASP.NET的代码生成器在控制层次结构建立过程中,使用它们的认构造函数来新闻这些控件.当您希望此功能适用于它们时,您需要使用自定义的PageHandlerFactory来挂接这些控件的PreInit事件,因为在构建页面类的时候,相关的控件和用户控件尚未创建.然而,要在其上注册PreInit事件,您需要在页面类中找到这些控件,并且我们需要反映页面类.由于控件存储在非公共实例字段中,因此这不会在部分信任中起作用.

无论是否是您的应用程序无法以部分信任方式运行的问题取决于您,但由于.NET 4的安全模型已被大大简化,因此以部分信任方式运行Web应用程序非常容易,这是我的一些努力做

TLDR;因此,总而言之,可以这样做(参见例如this example),但由于ASP.NET Web窗体框架的限制,您需要完全信任地运行以使其正常工作.

UPDATE从.NET 4.0开始,Microsoft已经废除了ASP.NET的部分信任(见here).所以从这个角度来看,远离完全信任可能不是那么有用(反正你还需要).

原文地址:https://www.jb51.cc/aspnet/250679.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐