Frequently Asked Questions

What are the reasons for minimizing any dependencies on the container?

It is good practice is to minimize the dependency between your application and the IoC framework as it increases the maintainability and testability of the application which results in cleaner code. We work hard to ensure you are not locked in to using Simple Injector. You will not find interfaces for mocking or attributes for governing object lifetime. We urge you at all times to keep references to Simple Injector (or any DI container for that matter) to the absolute minimum - ideally the only reference to the Container should be in the Composition Root. Minimizing lock-in can be achieved by designing the types in your application around the constructor injection pattern, which means that you define all dependencies of a class as parameters of the single public constructor of that type. Do this for all service types that need to be resolved and resolve only the top most types in the application directly (let the container build up the complete graph of dependent objects for you).

What makes Simple Injector so fast?

Simple Injector makes use of .NET 2.0 Generics and .NET 3.5 Func<T> delegates and Expression trees for type safe, code-based configuration. Internally, the container has a dictionary of registered types and expression trees.

The process of registering types in the container simply stores the definitions of the intention to produce such an instance - there is no compilation of delegates during the registration phase. Users are allowed to register types in any order so the container must wait until the end of the registration phase to be in a position to fully understand all of the types and their dependencies and their lifetimes.

Once the registration phase is complete the container is "locked down" (this happens the first time an instance is requested from the container). At this point in time the container is able to compile all of the delegates that construct graphs of objects by interrogating the parameter types in each type's constructor, a technique which is known as automatic constructor injection or auto-wiring.

It is these compiled delegates that give Simple Injector its incredible performance.

More ...

Why is the container locked-down to prevent registration changes?

Most frameworks do not put a limit on flexibility by locking the container and have a philosophy of “if you want to shoot yourself in the foot, then shoot yourself in the foot”. Simple Injector is different. Simple Injector does all it can to guarantee a consistence response.

Consider this simple example:
  • User resolves IService.
  • IService depends on IConnection
  • IService is created (with a reference to an instance of IConnection) and since IService is configured as singleton, it is cached in the container
  • Later on the user changes the registration of IConnection
  • The user resolves IService
  • The container has 2 choices:
    1. Return the cached instance of IService that has a reference to the "wrong" IConnection
    2. Create and cache a new instance of IService and in doing so break the promise of the type being registered as a singleton

Why forces Simple Injector my registered types to have a single constructor?

class UserService : IUserService
    private readonly IUserRepository repository;

    public UserService(IUserRepository repository)
        this.repository = repository;

    // ...

Violating the one-constructor convention leads to ambiguity; ambiguity leads to maintainability issues.

More ...

Last edited May 23, 2014 at 4:57 PM by dot_NET_Junkie, version 2