Type creation during container Verify

Aug 15, 2013 at 9:35 PM
Hi,

Sorry, it's me again. :)

I've successfully eradicated all existence of Unity from my application. Everything is now on Simple Injector. I have completely reworked registration so everything, including "drop-in" module discovery is done prior to Verify.

My question is around what happens during Verify. The application has registered countless items, the majority as types, around 10 as SingleInstance.

If I place a breakpoint in some constructors, they appear to be created when I expect (i.e. they are part of a constructors parameters in a single instance).

Interestingly, I have registered a type using container.RegisterType<T>(), which I don't think is anything in itself, but that type gets created and I cannot see why. If I look at the stack trace, the previous line of code in my application is Verify.

This type is recreated when I do the action in the application that should have the type resolved, so that bit is at least OK, but I am getting an unwanted side effect since the type is being created during Verify when I don't think it should be.

Might you have any idea why this could be?

Cheers,

Simon
Coordinator
Aug 15, 2013 at 10:01 PM
Hi Simon,

The only way to have confidence that a type can be resolved, is by actually resolving that type. So that's what Verify does: it iterates all registrations and requests an instance of that type. This has the following advantages:
  • By actually executing the code, the constructor, any injected properties, any advanced expression rewriting rules, registered initializers, and more, are tested.
  • Resolving each instance once forces all expressions to be created, compiled, and all code to be JITted at that point. This prevents any costly initialization from happening later on.
The down sides however are:
  • For some configurations the verification process takes to long making the application to start up too slowly.
  • All singletons are created at that point, as you experienced. This should usually however not be a problem.
So calling Verify is not always suited. My advice however is to always start by calling Verify() in the Composition Root after you made the last registration. Only when this process starts to take to long (or it is not suited for your configuration), fall back to moving that Verify call to your unit/integration tests. By at least calling Verify in your unit tests, you have some certainty about the correctness of your configuration.
Marked as answer by dot_NET_Junkie on 2/26/2014 at 1:45 PM
Aug 15, 2013 at 10:08 PM
Hi,

Thanks for the prompt reply.

I can see what you're saying and total agree with the testing and confidence side of things.

I guess I could re-bake my model and the view that uses it so the side effect is eradicated, so I'll go ahead and do that. :)

One more question; I tried not calling Verify, but ended up with none of my SingleInstance types being created. If I do choose to skip Verify for performance reasons, do I need to call GetInstance<> for each SingleInstance registered type?

Simon
Coordinator
Aug 15, 2013 at 10:28 PM
Edited Feb 26, 2014 at 9:44 PM
If you don't call Verify, the framework just acts as lazy as possible (the exact opposite of calling Verify). Any singletons will get created just when they are needed for the first time. This will happen when you request them directly or you request a type that directly or indirectly depends on that singleton. It might seem that the container sometimes creates the singleton too early, but most often because of internal performance optimizations.
Aug 15, 2013 at 10:32 PM
I think I'm now totally done, up and running. \o/

The singletons that I consider absolutely core I am creating with "new", then registering them in the container as the earliest registrations using container.RegisterSingle<T>(T inst). All modules are registering as RegisterSingle<T,TInst>() so they are resolved when first needed.

I can now not Verify the container and I would say my application loads much faster than when I was using Unity now.

I'm sure I may be back with more questions at some point, but for now thanks. :)

Simon