使用WebForms的简单注入器

时间:2015-10-22 01:37:15

标签: vb.net dependency-injection webforms ioc-container simple-injector

背景

我正在帮助另一位开发人员整理一个演示应用程序,作为创建测试的候选子,使用DI容器,项目结构和其他可以提高代码质量的东西,同时希望我们能够更快地发布更多可用的软件。

在本演示中,我想使用Simple Injector。我已按照他们的文档上的integration guide来获取此部分的DI部分并运行。我遇到的障碍是在启动网站时。我收到了这个错误。

  

配置无效。报告了以下诊断警告:    - [Disposable Transient Component] _Default注册为transient,但实现了IDisposable。   有关警告的详细信息,请参阅Error属性。请参阅https://simpleinjector.org/diagnostics如何解决问题以及如何压制个别警告。

以下是webform的背后代码

Public Class _Default
    Inherits System.Web.UI.Page

    <Import>
    Public Property TrueService As ITrueService

    Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
        lbl.Text = TrueService.ReturnsTrue().ToString()
    End Sub

End Class

这是我在应用程序启动时调用的方法。

Private Shared Sub Bootstrap()
    ' 1. Create a new Simple Injector container.
    Dim container = New Container()
    container.Options.DefaultScopedLifestyle = new WebRequestLifestyle()

    ' Register a custom PropertySelectionBehavior to enable property injection.
    container.Options.PropertySelectionBehavior = New ImportAttributePropertySelectionBehavior()

    ' 2. Configure the container (register)
    container.Register(Of ITrueRepository, TrueRepository)(Lifestyle.Scoped)
    container.Register(Of ITrueService, TrueService)(Lifestyle.Scoped)

    ' Register your Page classes.
    RegisterWebPages(container)

    ' 3. Store the container for use by Page classes.
    _container = container

    ' 4. Optionally verify the container's configuration.
    '    Did you know the container can diagnose your configuration?
    '    For more information, go to: https://simpleinjector.org/diagnostics.
    container.Verify()
End Sub

在container.Verify()中抛出异常。无论是否设置了DefaultScopedLifestyle,我都试过这个。 Global.asax中的其他所有内容与其文档中的内容相同。

根据给出的错误信息,我应该注册我需要注册属性的页面吗?我认为这是由<Import>属性处理的。

编辑:澄清我正在通过Web应用程序项目执行此操作,因为我们计划很快转移到该项目。

EDIT2:@Steven的回答让魔术发生,页面加载。不幸的是,页面在浏览器中完成渲染后,ASP.NET会触发另一系列事件,我看到了这个错误:

  

SimpleInjector.dll中发生了'SimpleInjector.ActivationException'类型的异常,但未在用户代码中处理

     

无法找到RequestDataHttpHandler类型的注册,无法进行隐式注册。 RequestDataHttpHandler类型的构造函数包含String类型的参数'requestId',它不能用于构造函数注入。

使用此堆栈跟踪:

at SimpleInjector.Container.ThrowNotConstructableException(Type concreteType)
at SimpleInjector.Container.ThrowMissingInstanceProducerException(Type serviceType)
at SimpleInjector.Container.ThrowInvalidRegistrationException(Type serviceType, InstanceProducer producer)
at SimpleInjector.Container.GetRegistration(Type serviceType, Boolean throwOnFailure)
at DITest.UI.Application.GlobalAsax.InitializeHandler(IHttpHandler handler) in C:\Users\slmartin\Documents\Visual Studio 2015\Projects\DITest\DITest.UI.Application\Global.asax.vb:line 41
at DITest.UI.Application.PageInitializerModule._Closure$__2-0._Lambda$__0(Object sender, EventArgs e) in C:\Users\slmartin\Documents\Visual Studio 2015\Projects\DITest\DITest.UI.Application\Global.asax.vb:line 26
at DITest.UI.Application.PageInitializerModule._Closure$__2-0._Lambda$__R1(Object a0, EventArgs a1)
at System.Web.HttpApplication.SyncEventExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)

在此方法中会发生这种情况,该方法是从PageInitializerModule中的Init方法调用的:

Public Shared Sub InitializeHandler(handler As IHttpHandler)
    _container.GetRegistration(handler.GetType(), True).Registration.InitializeInstance(handler)
End Sub

1 个答案:

答案 0 :(得分:2)

从Simple Injector v3开始,容器现在更加严格地验证配置的正确性。调用Verify时,将运行诊断程序,并在配置出现问题时引发异常。虽然这是一个非常好的变化,但这是一个突破性的变化。

不幸的是,我们忘记在发布期间更新Web表单的集成指南。您必须将RegisterWebPages方法改为以下(请原谅我的C#)以下内容:

private static void RegisterWebPages(Container container)
{
    var pageTypes =
        from assembly in BuildManager.GetReferencedAssemblies().Cast<Assembly>()
        where !assembly.IsDynamic
        where !assembly.GlobalAssemblyCache
        from type in assembly.GetExportedTypes()
        where type.IsSubclassOf(typeof(Page))
        where !type.IsAbstract && !type.IsGenericType
        select type;

    foreach (Type type in pageTypes)
    {
        var registration = Lifestyle.Transient.CreateRegistration(type, container);
        registration.SuppressDiagnosticWarning(
            DiagnosticType.DisposableTransientComponent,
            "ASP.NET creates and disposes page classes for us.");
        container.AddRegistration(type, registration);
    }
}

我们将相应更新集成指南。

请参阅the documentation,了解如何与最新版本的Simple Injector集成。