加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > asp.Net > 正文

为什么每个人都在ASP.NET Webforms中依赖注入是困难的,当PageHan

发布时间:2020-12-15 23:39:40 所属栏目:asp.Net 来源:网络整理
导读:所以我有一个遗留的webforms网站,正在努力使它更容易维护.把它拿走并重写它不是一个选择. IoC显然是它得到的第一件事情,但这给我留下了服务定位模式和不好的味道,以及是否可以做得更好. 我已经在线聊天的各位告诉我,我可以使用一个HttpModule进行属性注入,该
所以我有一个遗留的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).所以从这个角度来看,远离完全信任可能不是那么有用(反正你还需要).

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读