Idea: Automatic Lifetime Scopes for Constructor Dependency Injection

I just had this idea to derive the lifetime scopes of instances automatically from their dependencies.

Given that

  1. Only constructor injection is used (which is the kind of purity I prefer).
  2. Nested lifetime scopes and new instances are created only by constructors having the argument types of Func<Instance> or Func<Argument, Instance>.

… the “intended” lifetime scope of all resolved instances can be derived by one simple rule:

  • When an instance is resolved, it is bound in the current or first ancestor scope that fulfills the closure of all its dependencies.

Of course there is one exception: Func<> returned instances and their arguments “need” to be created in a new nested scope.

An example (simplified to constructors):

  • PersonName(string)
  • PersonsFriends(PersonName)
  • Person(PersonName, PersonsFriends)

Whenever a Func<PersonName, Person> generator is used, PersonName is bound to the new lifetime scope and implicitly forces PersonsFriends also to be bound to the same scope, because the dependency PersonName can be fulfilled.

This solves one essential problem with dependency injectors with nested lifetime scoping:

If an instance of PersonsFriends already exists in an ancestor scope, it would be used instead of a new instance. In other words, it would just silently “shadow” an instance that is parameterized differently.

Now, by tracking down the closure of all dependencies, the lifetime scope chosen for the instance would be just right.

This problem was bothering me for some time and was indeed the most confusing behavior of my constructor dependency injector.

    I doubt hope that the implementation will be simple.