aspnet/DependencyInjection — pull request #121 by halter73 (2014-10-15 03:50:32+00:00)
Title: IServiceProvider.GetService should return null for unregistered services

This PR does far more than just change our IServiceProvider implementations to return null for missing services (note that GetService will still throw if the top-level service exists but cannot be instantiated because of missing dependencies in the graph), but it was hard to encapsulate all this PR does in the title.

This PR introduces the concept of an IServiceCallSite which has two methods: Invoke an Build.

IServiceCallSite.Invoke basically does the same thing that IService.Create use to do, which is basically to create a service and return a service instance. There are various ways this is done based on the type of service being resolved, but this is commonly done by calling ConstructorInfo.Invoke and resolving dependencies using recursively as necessary.

IServiceCallSite.Build method creates an Expression that does the exact same thing Invoke does. However this single expression tree includes all the code necessary to resolve the entire dependency graph without any recursive calls. Obviously, the expression tree itself is built recursively.

IServiceCallSite.Invoke is called the first few times a service is resolved, since these expression trees can be expensive to build. However, once a service is resolved the second time, a job is kicked asynchronously of to build the expression tree that will resolve the service after it's built.