Deep down in the Registration class, during the generation of a NewExpression, the class causes the InstanceProducer instance for each dependency twice.
The first request is through the IDependencyInjectionBehavior.BuildExpression interface and is used to build up the actual expression tree. The BuildExpression implemention than calls back into the container to call the Container's internal GetRegistrationEvenIfInvalid method.
The second request when the Registration builds up the list of 'known relationships'. It does this by calling (again) into the GetRegistrationEvenIfInvalid method.
Requesting such InstanceProducer twice normally has no observable effect to the user, except when the dependency is a conditional registration. In that case the registration's predicate will be called twice, with the exact same context.
Although the performance penalty is usually low, it is confusing and counter intuitive that the library allways calls the predicate least twice for every consumer the dependency is injected into.
This unfortunate behavior is caused by the way Simple Injector has evolved over time. Simple Injector's diagnostic abilities (that use known relationships) did not exist during the time that the XXXBehavior strategies where added.
Since IDependencyInjectionBehavior is an important extension point through which users can change the way dependencies are constructed, the use of IDependencyInjectionBehavior can't be removed from Registration. Likewise does Registration need to get the InstanceProducer dependencies to build the list of known types; the diagnostic system completely relies on this. The only way to fix this issue is to make a breaking change to the IDependencyInjectionBehavior interface to let it return the InstanceProducer. There are a few ways this can be done, depending on the level of change we allow to be made:
Every option has its pro's and con's. The third option will for instance require the creation of Expression based InstanceProducers to be simplified, since users now need to return a full InstanceProducer instead of just an Expression.
Made required structural changes
Made required structural changes to make it possible to call the
conditional predicate just once (Related to #346)
Fixed duplicate predicate invocation
(related to #346)