【问题标题】:Simple Injector and Web Forms - the correct approach for injecting into Pages, UserControls and MasterPages?简单注入器和 Web 表单 - 注入页面、用户控件和母版页的正确方法?
【发布时间】:2017-08-24 19:57:46
【问题描述】:

根据关于 WebForms 集成的 Simple Injector 文档,它通过代码示例说,我们应该通过使用 [Import] 属性将属性注入到我们的页面中。我们通过根据他们的代码示例连接 Global.asax 文件来启用此行为。它确实适用于 Pages。但是,UserControls 或 MasterPages 的文档中没有任何内容。

在搜索 StackOverflow 以获得可靠的答案时,普遍存在的响应有点过时,并且引用了创建 HttpModule,提供了指向在其 git 存储库 (SimpleInjector.Integration.Web.Forms) 中找到的示例项目的链接。不过,该示例项目已失效,并且从 Simple Injector v4.0 的 repo 中剔除。而且它根本不使用 [Import] 属性的东西。绝对令人困惑。

因此,在不清楚如何前进的情况下,我尝试将两者合并以使其正常工作。

我正在使用最新文档中详述的 Global.asax 引导程序方法,而不是注册新的 HttpModule。我采用了旧 WebForms 集成项目中定义的 container extension methods,并在我的 Bootstrap 中调用它们而不是旧方法。

   private static void Bootstrap()
    {
    var container = new Container();
//container.Options.PropertySelectionBehavior = new ImportAttributePropertySelectionBehavior();   //approach from latest documentation
            container.Options.PropertySelectionBehavior = new SimpleInjector.Integration.Web.Forms.WebFormsPropertySelectionBehavior(container.Options.PropertySelectionBehavior); //changed to using WebForms integration way
    ...
    //RegisterWebPages(ref container); //approach from latest documentation
    container.RegisterPages();       //changed to using WebForms integration extension methods
    }    

当我第一次运行它时,container.Verify() 抱怨每个 Page 都实现了 IDisposable 并且它们被注册为 Transient(这让我感到困惑,因为最初的引导似乎也将 Pages 注册为 Transient,但 Verify 确实做到了不要抛出任何错误)。

因此,为了解决这个问题,我将 RegisterPages 扩展方法修改为默认为 Lifestyle.Scoped,从而消除了验证错误。

private static void RegisterBatchAsConcrete(this Container container, IEnumerable<Type> types)
        {
            foreach (Type concreteType in types)
            {
                //container.Register(concreteType);  //originally registering Transient
                container.Register(concreteType, concreteType, Lifestyle.Scoped);
            }
        }

而且它现在似乎可以工作了,至少对于 Pages 来说是这样。在继续为 UserControls 和 MasterPages 工作之前,我想知道以下问题的答案:

问题

这是正确的方法吗?我是否会因为将 Page、MasterPage 和 UserControl 注册从 Transient 更改为 Scoped 生活方式而遇到问题(性能或其他问题)?还有其他我没有想到的问题吗?

为什么使用 RegisterPages 扩展方法调用与新的 RegisterWebPages 方法相比,Verify 对 Tranisent Lifestyle 有问题?

我应该实际使用 Import 属性,还是不使用?新方法使用 ImportAttributePropertySelectionBehavior,而旧方法使用 WebFormsPropertySelectionBehavior

【问题讨论】:

    标签: asp.net dependency-injection webforms inversion-of-control simple-injector


    【解决方案1】:

    不过,该示例项目已失效,并且从 Simple Injector v4.0 的存储库中剔除。

    SimpleInjector.Integration.Web.Forms) 是很久以前构建的,旨在成为将 Web 表单与 Simple Injector 集成的解决方案。由于社区缺乏兴趣(即,对将 Simple Injector 与 Web 窗体集成感兴趣的开发人员太少),我们决定不投资将其发布为 NuGet 包,维护它,创建文档,修复错误,支持它等等。

    由于 Web 表单是一项遗留技术,我们最终决定从存储库中提取项目,因为我们知道我们始终可以引用旧分支。

    而且它根本不使用 [Import] 属性的东西。绝对令人困惑。

    那不是真的。 [Import] 也可以,但作为文档 describes,您必须插入您的自定义 ImportAttributePropertySelectionBehavior

    为什么使用 RegisterPages 扩展方法调用与新的 RegisterWebPages 方法相比,Verify 在 Transient Lifestyle 方面存在问题?

    integration guide for Web Forms 抑制了DisposableTransientComponent 警告,因此您也必须这样做。在集成项目中没有发生这种情况的原因是因为这个项目是在 v2.x 时间范围内创建的,当时验证没有那么严格。此后该项目从未更新过。

    这是正确的方法吗?我是否会因为将 Page、MasterPage 和 UserControl 注册从 Transient 更改为 Scoped 生活方式而遇到问题(性能或其他问题)?还有其他我没有想到的问题吗?

    你绝对应该将你的类和用户控制器注册为作用域,因为你很快就会遇到严重的麻烦。尤其是对于用户控件,在页面中有同一个控件的多个实例是很常见的。将它们注册为Scoped 会导致同一个实例被放置在页面中的多个位置,这显然会造成麻烦(如果它确实有效的话)。

    因此,您绝对应该将用户控件(可能还有页面)注册为Transient,并取消DisposableTransientComponent 警告。 DisposableTransientComponent 可以被抑制,因为 ASP.NET 会在请求结束时为您处理所有内容。

    我应该实际使用 Import 属性,还是不使用?新方法使用 ImportAttributePropertySelectionBehavior,而旧方法使用 WebFormsPropertySelectionBehavior

    ImportAttributePropertySelectionBehavior 使用[Import] 属性实现Explicit Property Injection,而WebFormsPropertySelectionBehavior 实现Implicit Property Injection

    决定使用什么由您决定,但通常应该首选显式属性注入,因为隐式属性注入(文档描述)的缺点。

    【讨论】:

    • 当我输入这个的时候,我希望你能回复,但没想到你这么快!那么,要注入 MasterPages 和 UserControls,我应该使用 Global asax bootstrap 方法(推荐用于页面注入)还是集成项目中推荐的 HttpModule 方法?我知道 WebForms 被许多人认为是一种遗留技术,并且我确实理解为什么将它从项目中撤出。我不是在批评这个决定——我只是想对如何做到这一点有一个可靠的答案,因为我确信我们中的另外半打仍然必须使用 WebForms。
    • 两者实际上都使用了 IHttpModule,但请注意,文档中的示例过滤掉了某些处理程序,这是项目不做的事情(因为它从未真正在实际应用程序中进行过测试)。所以你必须混合搭配。
    猜你喜欢
    • 2018-10-08
    • 2023-03-10
    • 2016-02-22
    • 1970-01-01
    • 2016-12-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多