简单的注入器和Web表单 - 注入Pages,UserControls和MasterPages的正确方法?

时间:2017-08-24 19:57:46

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

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

在搜索StackOverflow以获得可靠的答案时,无处不在的响应稍微过时,并且引用创建了一个HttpModule,提供了一个链接到他们的git repo(SimpleInjector.Integration.Web.Forms)中的示例项目。然而,这个示例项目已经死亡并且从Simple Injector v4.0中的回购中剔除了。并且它根本不使用[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(这让我感到困惑,因为原始的bootstrapping似乎也将Pages注册为Transient,但是验证没有抛出任何错误)。

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

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方法验证Tranisent Lifestyle是否存在问题?

我实际上应该使用Import属性吗?新方法使用ImportAttributePropertySelectionBehavior,而旧方法使用WebFormsPropertySelectionBehavior

1 个答案:

答案 0 :(得分:1)

  

那个示例项目已经死了,并且从Simple Injector v4.0开始就从repo中剔除了。

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

由于Web Forms是一项传统技术,我们最终决定从存储库中提取项目,因为我们知道我们总是可以引用较旧的分支。

  

它根本不使用[Import]属性。绝对令人困惑。

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

  

为什么使用RegisterPages扩展方法调用与新的RegisterWebPages方法验证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

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