Background
I'm helping another developer put together a demo application as a poster child for creating tests, using a DI Container, project structure and other things that will increase code quality while hopefully allowing us to release more usable software faster.
In this demo I want to use Simple Injector. I've followed the integration guide on their docs to get the DI portion of this up and running. The snag I've hit is when getting the site to launch. I get this error.
The configuration is invalid. The following diagnostic warnings were reported: -[Disposable Transient Component] _Default is registered as transient, but implements IDisposable. See the Error property for detailed information about the warnings. Please see https://simpleinjector.org/diagnostics how to fix problems and how to suppress individual warnings.
Here is the code behind for the 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
And here is the method I call in the application start.
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
The exception is thrown in container.Verify(). I have tried this with and without setting the DefaultScopedLifestyle. Everything else in the Global.asax is the same as what's given in their docs.
Based on the error message given, am I supposed to register the pages where I need the property injection? I thought this was taken care of with the <Import>
attribute.
EDIT: To clarify I am doing this with a web application project as we plan to move to that soon.
EDIT2: @Steven's answer lets the magic happen and the page loads. Unfortunately after the page finishes rendering in the browser ASP.NET fires off another series of events and I see this error:
An exception of type 'SimpleInjector.ActivationException' occurred in SimpleInjector.dll but was not handled in user code
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.
With this stack trace:
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)
This happens in this method, which is called from the Init method in the PageInitializerModule:
Public Shared Sub InitializeHandler(handler As IHttpHandler)
_container.GetRegistration(handler.GetType(), True).Registration.InitializeInstance(handler)
End Sub