Several last projects I used a simple IoC container, leveraging Activator.CreateInstance(type). The main reason - simplicity. Once there was a need to go to a higher level, I would switch to Windsor Container. One of the projects used Unity. The only issue was that I would always have to do some customization to my container (or DependencyResolver), which is nothing but a static gateway.
What I have decided, is that I do not want to invest effort in something that was working before just because the underlying implementation of container has changed. The container engine might be changed, but my code should not (OCP?). Therefore, DependencyResolver had to be coded slightly different. To make it possible, I decided to go with the LINQ Expressions. It allows to pass code in data structures, and thus allows to manipulate how to execute the code.
For demonstration purposes, I will only demonstrate the simple case, more complex cases are feasible as well.
DependencyResolver (which is static gateway) is
By default, LambdaDependencyResolver is going to be used. Registration is done by passing in an Expression<Func<ContractType>> that is nothing but a function that returns a ContractType implementer. The idea to wrap it with Expression, so that the instance (a particular dependency resolver implementation) would take care of the details based on how it works.
It's working, great. Some time later, we need to switch to some 3rd party container, and we don't want to change our code that relies on DependencyResolver. This is where Expressions are handy. I have used Unity container, but that could be StructureMap, Windsor Container, or anything else.
Bolded code in LambdaDependencyResolver and UnityDependencyResolver is simply leveraging LINQ Expressions to make it all work. You can definitely make it more sophisticated and elegant as needed.