【问题标题】:Simple Injector with WebForms带有 WebForms 的简单注入器
【发布时间】:2016-01-21 04:51:33
【问题描述】:

背景

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

在这个演示中,我想使用 Simple Injector。我已经在他们的文档上关注了integration guide,以启动并运行该 DI 部分。我遇到的障碍是让网站启动时。我收到此错误。

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

这是网络表单的代码

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 中的其他所有内容都与他们的文档中给出的相同。

根据给出的错误消息,我应该注册需要属性注入的页面吗?我认为这是通过 &lt;Import&gt; 属性处理的。

编辑:澄清一下,我正在使用一个 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

【问题讨论】:

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


    【解决方案1】:

    自 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 集成。

    【讨论】:

    • 这回答了我的问题,但我现在遇到了另一个问题。当从 PageInitializerModule 调用 Global.InitializeHandler 时出现异常。该页面将加载并显示,但这会在之后调用。 Additional information: No registration for type RequestDataHttpHandler could be found and an implicit registration could not be made. The constructor of type RequestDataHttpHandler contains parameter 'requestId' of type String which can not be used for constructor injection.
    • @Slowbad:请更新您的问题并添加完整的堆栈跟踪\。
    • @Slowbad:RequestDataHttpHandler 是你定义的吗?那个处理程序是从哪里来的?
    • 我没有创建那个类。粗略的谷歌搜索显示这是来自 Visual Studio 的东西,Microsoft.VisualStudio.Web.PageInspector.Runtime。我找到了Simple Injector discussion boards 的链接。它试图解决类似的问题,但我不知道 MVC 有多少是特定的。
    • 最简单的方法是让 InitializeHandler 方法跳过这个特定的处理程序类型。事实上,MVC 集成包包含更持久的方法,但这需要更多的工作。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-07-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多