Do I need to pass in the same scoped lifestyle instance (Follow on from StackOverflow question)

Jun 2, 2014 at 12:00 PM
Edited Jun 2, 2014 at 12:08 PM
There was a recent question on stackoverflow asking whether this code
container.Register(() => new MyClass1(), new WebApiRequestLifestyle());
container.Register(() => new MyClass2(), new WebApiRequestLifestyle());
is better than this
var webApiRequestLifestyle = new WebApiRequestLifestyle();
container.Register(() => new MyClass1(), webApiRequestLifestyle);
container.Register(() => new MyClass2(), webApiRequestLifestyle);
The answer explained in detail why the second option is better than the first.

Why doesn't the container optimise the first option internally to be the same as the second option?

If it's not a good idea to implement this optimisation then is registering multiple scope instances of the same type a candidate for a new verification in the diagnostics services?
Jun 2, 2014 at 12:18 PM
Edited Jun 3, 2014 at 5:52 AM
The reason for not doing this optimization is because multiple instances of the same lifestyle could in theory return a different Scope. Just take a look at the following example:
var lifestyle1 = new FixedScopeLifestyle(new Scope());
var lifestyle2 = new FixedScopeLifestyle(new Scope());

container.Register<IUserRepository, SqlUserRepository>(lifestyle1);
container.Register<IOrderRepository, SqlOrderRepository>(lifestyle2);
Here two instances of the FixedScopeLifestyle are used and both return their own Scope class. If the container would optimize the object graph simply based on the lifestyle type, the example above would break, because in that case only one of the scopes would be used to resolve both repositories, which is clearly not what the user expected here.

Simple Injector would however still be able to do the optimization for its built-in lifestyles, but this is a bit tricky, because:
  • None of the built-in ScopedLifestyle implementations are in the core library, and the core library doesn't have a reference to it.
  • It could to the check based on the namespace of the type (say SimpleInject.), this could still break if a user creates a custom lifestyle and places it in a SimpleInjector. namespace.
  • If a future a feature is added that depends on this lack of optimization, it will break when this new integration package is used with an older version of the core library.
That's why the current release doesn't do such optimization.

Of course this is an implementation detail, and is subject to change. There's a change that a future version does this optimization.