Advanced Scenarios

Although its name may not imply it, Simple Injector is capable of handling many advanced scenarios. Either through writing custom code, copying code from this wiki, or via the extension points that can be found in the SimpleInjector.Extensions namespace of the core library.

Note: After including the SimpleInjector.dll in your project, you will have to add the SimpleInjector.Extensions namespace to your code to be able to use the majority of features that are presented in this wiki page.

This page discusses the following subjects:

Generics

.NET has superior support for generic programming and Simple Injector has been designed to make full use of it. Simple Injector arguably has the most advanced support for generics of all DI libraries. Simple Injector can handle any generic type and implementing patterns such as decorator, mediator, strategy and chain of responsibility is simple.

Aspect Oriented Programming is easy with Simple Injector’s advanced support for generics. Generic decorators with generic type constraints can be registered with a single line of code and can be applied conditionally using predicates. Simple Injector can handle open generic types, closed generic types and partially-closed generic types. The sections below provides more detail on Simple Injector’s support for generic typing:

Batch / Automatic registration

Batch or automatic registration is a way of registering a set of related types in one go based on some convention. This features removes the need to constantly update the container’s configuration each and every time a new type is added. The following example show a series of manually registered repositories:

container.Register<IUserRepository, SqlUserRepository>();
container.Register<ICustomerRepository, SqlCustomerRepository>();
container.Register<IOrderRepository, SqlOrderRepository>();
container.Register<IProductRepository, SqlProductRepository>();
// and the list goes on...

To prevent having to change the container for each new repository we can use the non-generic registration overloads in combination with a simple LINQ query:

var repositoryAssembly = typeof(SqlUserRepository).Assembly;

var registrations =
    from type in repositoryAssembly.GetExportedTypes()
    where type.Namespace == "MyComp.MyProd.BL.SqlRepositories"
    where type.GetInterfaces().Any()
    select new { Service = type.GetInterfaces().Single(), Implementation = type };

foreach (var reg in registrations) {
    container.Register(reg.Service, reg.Implementation, Lifestyle.Transient);
}

Although many other DI libraries contain an advanced API for doing convention based registration, we found that doing this with custom LINQ queries is easier to write, more understandable, and can often prove to be more flexible than using a predefined and restrictive API.

Another interesting scenario is registering multiple implementations of a generic interface. Say for instance your application contains the following interface:

public interface IValidator<T> {
    ValidationResults Validate(T instance);
}

Your application might contain many implementations of this interface for validating Customers, Employees, Products, Orders, etc. Without batch registration you would probably end up with a set registration similar to those we’ve already seen:

container.Register<IValidator<Customer>, CustomerValidator>();
container.Register<IValidator<Employee>, EmployeeValidator>();
container.Register<IValidator<Order>, OrderValidator>();
container.Register<IValidator<Product>, ProductValidator>();
// and the list goes on...

By using the extension methods for batch registration of open generic types from the SimpleInjector.Extensions namespace the same registrations can be made in a single line of code:

container.RegisterManyForOpenGeneric(typeof(IValidator<>),
    typeof(IValidator<>).Assembly);

By default RegisterManyForOpenGeneric searches the supplied assembly for all types that implement the IValidator<T> interface and registers each type by their specific (closed generic) interface. It even works for types that implement multiple closed versions of the given interface.

Note: There are numerous RegisterManyForOpenGeneric overloads available that take a list of System.Type instances, instead a list of Assembly instances.

Above are a couple of examples of the things you can do with batch registration. A more advanced scenario could be the registration of multiple implementations of the same closed generic type to a common interface, i.e. a set of types that all implement the same interface. There are so many possible variations of this scenario that Simple Injector does not contain an explicit method to handle this. What it does contain, however, are multiple overloads of the RegisterManyForOpenGeneric method that allow you to supply a callback delegate that enables you make the registrations yourself.

As an example, imagine the scenario where you have a CustomerValidator type and a GoldCustomerValidator type and they both implement IValidator<Customer> and you want to register them both at the same time. The earlier registration methods would throw an exception alerting you to the fact that you have multiple types implementing the same closed generic type. The following registration however, does enable this scenario:

container.RegisterManyForOpenGeneric(typeof(IValidator<>),
    (serviceType, implTypes) => container.RegisterAll(serviceType, implTypes),
    typeof(IValidator<>).Assembly);

The code snippet registers all types from the given assembly that implement IValidator<T>. As we now have multiple implementations the container cannot inject a single instance of IValidator<T> and because of this, we need to supply a callback delegate. This allows us to override the way the registration is made, and allows us to make a registration for a collection. Because we register a collection, we can no longer call container.GetInstance<IValidator<T>>(). Instead instances can be retrieved by having an IEnumerable<IValidator<T>> constructor argument or by calling container.GetAllInstances<IValidator<T>>().

It is not generally regarded as best practice to have an IEnumerable<IValidator<T>> dependency in multiple class constructors (or accessed from the container directly). Depending on a set of types complicates your application design, can lead to code duplication. This can often be simplified with an alternate configuration. A better way is to have a single composite type that wraps IEnumerable<IValidator<T>> and presents it to the consumer as a single instance, in this case a CompositeValidator<T>:

public class CompositeValidator<T> : IValidator<T> {
    private readonly IEnumerable<IValidator<T>> validators;

    public CompositeValidator(IEnumerable<IValidator<T>> validators) {
        this.validators = validators;
    }

    public ValidationResults Validate(T instance) {
        var allResults = ValidationResults.Valid;

        foreach (var validator in this.validators) {
            var results = validator.Validate(instance);
            allResults = ValidationResults.Join(allResults, results);
        }

        return allResults;
    }
}

This CompositeValidator<T> can be registered as follows:

container.RegisterOpenGeneric(typeof(IValidate<>), typeof(CompositeValidator<>),
    Lifestyle.Singleton);

This registration maps the open generic IValidator<T> interface to the open generic CompositeValidator<T> implementation. Because the CompositeValidator<T> contains an IEnumerable<IValidator<T>> dependency, the registered types will be injected into its constructor. This allows you to let the rest of the application simply depend on the IValidator<T>, while registering a collection of IValidator<T> implementations under the covers.

Note: Simple Injector preserves the lifestyle of instances that are returned from an injected IEnumerable<T> instance. In reality you should not see the the injected IEnumerable<IValidator<T>> as a collection of implementations, you should consider it a stream of instances. Simple Injector will always inject a reference to the same stream (the IEnumerable<T> itself is a singleton) and each time you iterate the IEnumerable<T>, for each individual component, the container is asked to resolve the instance based on the lifestyle of that component. Regardless of the fact that the CompositeValidator<T> is registered as singleton the validators it wraps will each have their own specific lifestyle.

The next section will explain mapping of open generic types (just like the CompositeValidator<T> as seen above).

Registration of open generic types

When working with generic interfaces, we will often see numerous implementations of that interface being registered:

container.Register<IValidate<Customer>, CustomerValidator>();
container.Register<IValidate<Employee>, EmployeeValidator>();
container.Register<IValidate<Order>, OrderValidator>();
container.Register<IValidate<Product>, ProductValidator>();
// and the list goes on...

As the previous section explained, this can be rewritten to the following one-liner:

container.RegisterManyForOpenGeneric(typeof(IValidate<>),
    typeof(IValidate<>).Assembly);

Sometimes you’ll find that many implementations of the given generic interface are no-ops or need the same standard implementation. The IValidate<T> is a good example. It is very likely that not all entities will need validation but your solution would like to treat all entities the same and not need to know whether any particular type has validation or not (having to write a specific empty validation for each type would be a horrible task). In a situation such as this we would ideally like to use the registration as described above, and have some way to fallback to some default implementation when no explicit registration exist for a given type. Such a default implementation could look like this:

// Implementation of the Null Object pattern.
class NullValidator<T> : IValidate<T> {
    public ValidationResults Validate(T instance) {
        return ValidationResults.Valid;
    }
}

We could configure the container to use this NullValidator<T> for any entity that does not need validation:

container.Register<IValidate<OrderLine>, NullValidator<OrderLine>>();
container.Register<IValidate<Address>, NullValidator<Address>>();
container.Register<IValidate<UploadImage>, NullValidator<UploadImage>>();
container.Register<IValidate<Mothership>, NullValidator<Mothership>>();
// and the list goes on...

This repeated registration is, of course, not very practical. Falling back to such a default implementation is a good example for unregistered type resolution. Simple Injector contains an event that you can hook into that allows you to fallback to a default implementation. The RegisterOpenGeneric extension method is built on top of this event to handle this specific scenario. The NullValidator<T> would be registered as follows:

// using SimpleInjector.Extensions;
container.RegisterOpenGeneric(typeof(IValidate<>), typeof(NullValidator<>));

The result of this registration is exactly as you would have expected to see from the individual registrations above. Each request for IValidate<Department>, for example, will return a NullValidator<Department> instance each time.

Note: Because the use of unregistered type resolution will only get called for types that are not explicitly registered this allows for the default implementation to be overridden with specific implementations. The RegisterManyForOpenGeneric method does not use unregistered type resolution; it explicitly registers all the concrete types it finds in the given assemblies. Those types will therefore always be returned, giving a very convenient and easy to grasp mix.

There’s an advanced version of RegisterOpenGeneric overload that allows applying the open generic type conditionally, based on a supplied predicate. Example:

container.RegisterOpenGeneric(typeof(IValidator<>), typeof(LeftValidator<>),
    c => c.ServiceType.GetGenericArguments().Single().Namespace.Contains("Left"));

container.RegisterOpenGeneric(typeof(IValidator<>), typeof(RightValidator<>),
    c => c.ServiceType.GetGenericArguments().Single().Namespace.Contains("Right"));

Simple Injector protects you from defining invalid registrations by ensuring that given the registrations do not overlap. Building on the last code snippet, imagine accidentally defining a type in the namespace “MyCompany.LeftRight”. In this case both open-generic implementations would apply, but Simple Injector will never silently pick one. It will throw an exception instead.

There are some cases where want to have a fallback implementation in the case that no other implementation was applied and this can be achieved by checking the Handled property of the predicate’s OpenGenericPredicateContext object:

container.RegisterOpenGeneric(typeof(IRepository<>), typeof(ReadOnlyRepository<>),
    c => typeof(IReadOnlyEntity).IsAssignableFrom(
        c.ServiceType.GetGenericArguments().Single()));

container.RegisterOpenGeneric(typeof(IRepository<>), typeof(ReadWriteRepository<>),
    c => !c.Handled);

In the case above we tell Simple Injector to only apply the ReadOnlyRepository<T> registration in case the given T implements IReadOnlyEntity. Although applying the predicate can be useful, in this particular case it’s better to apply a generic type constraint to ReadOnlyRepository<T>. Simple Injector will automatically apply the registered type conditionally based on it generic type constraints. So if we apply the generic type constraint to the ReadOnlyRepository<T> we can remove the predicate:

class ReadOnlyRepository<T> : IRepository<T> where T : IReadOnlyEntity { }

container.RegisterOpenGeneric(typeof(IRepository<>), typeof(ReadOnlyRepository<>));
container.RegisterOpenGeneric(typeof(IRepository<>), typeof(ReadWriteRepository<>),
    c => !c.Handled);

The final option in Simple Injector is to supply the RegisterOpenGeneric method with a partially-closed generic type:

// SomeValidator<List<T>>
var partiallyClosedType = typeof(SomeValidator<>).MakeGenericType(typeof(List<>));
container.RegisterOpenGeneric(typeof(IValidator<>), partiallyClosedType);

The type SomeValidator<List<T>> is called partially-closed, since although its generic type argument has been filled in with a type, it still contains a generic type argument. Simple Injector will be able to apply these constraints, just as it handles any other generic type constraints.

Mixing collections of open-generic and non-generic components

The RegisterManyForOpenGeneric overloads that take in a list of assemblies only select non-generic implementations of the given open-generic type. Open-generic implementations are skipped, because they often need special attention.

To register collections that contain both non-generic and open-generic components a RegisterAll overload is available that accept a list of Type instances. For instance:

container.RegisterAll(typeof(IValidator<>), new[] {
    typeof(DataAnnotationsValidator<>), // open generic
    typeof(CustomerValidator), // implements IValidator<Customer>
    typeof(GoldCustomerValidator), // implements IValidator<Customer>
    typeof(EmployeeValidator), // implements IValidator<Employee>
    typeof(OrderValidator) // implements IValidator<Order>
});

In the previous example a set of IValidator<T> implementations are supplied to the RegisterAll overload. This list contains one generic implementation, namely DataAnnotationsValidator<T>. This leads to a registration that is equivalent to the following manual registration:

container.RegisterAll<IValidator<Customer>>(
    typeof(DataAnnotationsValidator<Customer>),
    typeof(CustomerValidator),
    typeof(GoldCustomerValidator));

container.RegisterAll<IValidator<Employee>>(
    typeof(DataAnnotationsValidator<Employee>),
    typeof(EmployeeValidator));

container.RegisterAll<IValidator<Order>>(
    typeof(DataAnnotationsValidator<Order>),
    typeof(OrderValidator));

In other words, the supplied non-generic types are grouped by their closed IValidator<T> interface and the DataAnnotationsValidator<T> is applied to every group. This leads to three seperate IEnumerable<IValidator<T>> registrations. One for each closed-generic IValidator<T> type.

Note: RegisterAll is guaranteed to preserve the order of the types that you supply.

But besides these three IEnumerable<IValidator<T>> registrations, an invisible fourth registration is made. This is a registration that hooks onto the unregistered type resolution and this will ensure that any time an IEnumerable<IValidator<T>> for a T that is anything other than Customer, Employee and Order, an IEnumerable<IValidator<T>> is returned that contains the closed-generic versions of the supplied open-generic types; DataAnnotationsValidator<T> in the given example.

Note: This will work equally well when the open generic types contain type constraints. In that case those types will be applied conditionally to the collections based on their generic type constraints.

In most cases however, manually supplying the RegisterAll with a list of types leads to hard to maintain configurations, since the registration needs to be changed for each new validator we add to the system. Instead we can make use of the GetTypesToRegister of the OpenGenericBatchRegistrationExtensions class to find the types for us:

List<Type> typesToRegister = new List<Type> {
    typeof(DataAnnotationsValidator<>)
};

typesToRegister.AddRange(
    OpenGenericBatchRegistrationExtensions.GetTypesToRegister(container,
        typeof(IValidator<>), AppDomain.CurrentDomain.GetAssemblies()));

container.RegisterAll(typeof(IValidator<>), typesToRegister);
The RegisterManyForOpenGeneric overloads that accept a list of assemblies use this GetTypesToRegister method internally as well.

Unregistered type resolution

Unregistered type resolution is the ability to get notified by the container when a type that is currently unregistered in the container, is requested for the first time. This gives the user (or extension point) the change of registering that type. Simple Injector supports this scenario with the ResolveUnregisteredType event. Unregistered type resolution enables many advanced scenarios. The library itself uses this event for implementing the registration of open generic types. Other examples of possible scenarios that can be built on top of this event are resolving array and lists and covariance and contravariance. Those scenarios are described here in the advanced scenarios page.

For more information about how to use this event, please take a look at the ResolveUnregisteredType event documentation in the reference library.

Context based injection

Context based injection is the ability to inject a particular dependency based on the context it lives in (for change the implementation based on the type it is injected into). This context is often supplied by the container. Some DI libraries contain a feature that allows this, while others don’t. Simple Injector does not contain such a feature out of the box, but this ability can easily be added by using the context based injection extension method code snippet.

Note: In many cases context based injection is not the best solution, and the design should be reevaluated. In some narrow cases however it can make sense.

The most common scenario is to base the type of the injected dependency on the type of the consumer. Take for instance the following ILogger interface with a generic Logger<T> class that needs to be injected into several consumers.

public interface ILogger {
    void Log(string message);
}

public class Logger<T> : ILogger {
    public void Log(string message) { }
}

public class Consumer1 {
    public Consumer1(ILogger logger) { }
}

public class Consumer2 {
    public Consumer2(ILogger logger) { }
}

In this case we want to inject a Logger<Consumer1> into Consumer1 and a Logger<Consumer2> into Consumer2. By using the previous context based injection extension method, we can accomplish this as follows:

container.RegisterWithContext<ILogger>(dependencyContext => {
    var type = typeof(Logger<>).MakeGenericType(
        dependencyContext.ImplementationType);

    return (ILogger)container.GetInstance(type);
});

In the previous code snippet we registered a Func<DependencyContext, ILogger> delegate, that will get called each time a ILogger dependency gets resolved. The DependencyContext instance that gets supplied to that instance, contains the ServiceType and ImplementationType into which the ILogger is getting injected.

Note: Although building a generic type using MakeGenericType is relatively slow, the call to the Func<DependencyContext, TService> delegate itself is about as cheap as calling a Func<TService> delegate. If performance of the MakeGenericType gets a problem, you can always cache the generated types, cache InstanceProducer instances, or cache ILogger instances (note that caching the ILogger instances will make them singletons).
Note: Even though the use of a generic Logger<T> is a common design (with log4net as the grand godfather of this design), doesn’t always make it a good design. The need for having the logger contain information about its parent type, might indicate design problems. If you’re doing this, please take a look at this Stackoverflow answer. It talks about logging in conjunction with the SOLID design principles.

Decorators

The SOLID principles give us important guidance when it comes to writing maintainable software. The ‘O’ of the ‘SOLID’ acronym stands for the Open/closed Principle which states that classes should be open for extension, but closed for modification. Designing systems around the Open/closed principle means that new behavior can be plugged into the system, without the need to change any existing parts, making the change of breaking existing code much smaller.

One of the ways to add new functionality (such as cross-cutting concerns) to classes is by the use of the decorator pattern. The decorator pattern can be used to extend (decorate) the functionality of a certain object at run-time. Especially when using generic interfaces, the concept of decorators gets really powerful. Take for instance the examples given in the Registration of open generic types section of this page or for instance the use of an generic ICommandHandler<TCommand> interface.

Tip: This article describes an architecture based on the use of the ICommandHandler<TCommand> interface.

Take the plausible scenario where we want to validate all commands that get executed by an ICommandHandler<TCommand> implementation. The Open/Closed principle states that we want to do this, without having to alter each and every implementation. We can do this using a (single) decorator:

public class ValidationCommandHandlerDecorator<TCommand> : ICommandHandler<TCommand> {
    private readonly IValidator validator;
    private readonly ICommandHandler<TCommand> handler;

    public ValidationCommandHandlerDecorator(IValidator validator,
        ICommandHandler<TCommand> handler) {
        this.validator = validator;
        this.handler = handler;
    }

    void ICommandHandler<TCommand>.Handle(TCommand command) {
        // validate the supplied command (throws when invalid).
        this.validator.ValidateObject(command);

        // forward the (valid) command to the real command handler.
        this.handler.Handle(command);
    }
}

The ValidationCommandHandlerDecorator<TCommand> class is an implementation of the ICommandHandler<TCommand> interface, but it also wraps / decorates an ICommandHandler<TCommand> instance. Instead of injecting the real implementation directly into a consumer, we can (let Simple Injector) inject a validator decorator that wraps the real implementation.

The ValidationCommandHandlerDecorator<TCommand> depends on an IValidator interface. An implementation that used Microsoft Data Annotations might look like this:

using System.ComponentModel.DataAnnotations;

public class DataAnnotationsValidator : IValidator {

    void IValidator.ValidateObject(object instance) {
        var context = new ValidationContext(instance, null, null);

        // Throws an exception when instance is invalid.
        Validator.ValidateObject(instance, context, validateAllProperties: true);
    }
}

The implementations of the ICommandHandler<T> interface can be registered using the RegisterManyForOpenGeneric extension method:

// using SimpleInjector.Extensions;
container.RegisterManyForOpenGeneric(
    typeof(ICommandHandler<>),
    typeof(ICommandHandler<>).Assembly);

By using the following extension method, you can wrap the ValidationCommandHandlerDecorator<TCommand> around each and every ICommandHandler<TCommand> implementation:

// using SimpleInjector.Extensions;
container.RegisterDecorator(
    typeof(ICommandHandler<>),
    typeof(ValidationCommandHandlerDecorator<>));

Multiple decorators can be wrapped by calling the RegisterDecorator method multiple times, as the following registration shows:

container.RegisterManyForOpenGeneric(
    typeof(ICommandHandler<>),
    typeof(ICommandHandler<>).Assembly);

container.RegisterDecorator(
    typeof(ICommandHandler<>),
    typeof(TransactionCommandHandlerDecorator<>));

container.RegisterDecorator(
    typeof(ICommandHandler<>),
    typeof(DeadlockRetryCommandHandlerDecorator<>));

container.RegisterDecorator(
    typeof(ICommandHandler<>),
    typeof(ValidationCommandHandlerDecorator<>));

The decorators are applied in the order in which they are registered, which means that the first decorator (TransactionCommandHandlerDecorator<T> in this case) wraps the real instance, the second decorator (DeadlockRetryCommandHandlerDecorator<T> in this case) wraps the first decorator, and so on.

There’s an overload of the RegisterDecorator available that allows you to supply a predicate to determine whether that decorator should be applied to a specific service type. Using a given context you can determine whether the decorator should be applied. Here is an example:

container.RegisterDecorator(
    typeof(ICommandHandler<>),
    typeof(AccessValidationCommandHandlerDecorator<>),
    context => !context.ImplementationType.Namespace.EndsWith("Admins"));

The given context contains several properties that allows you to analyze whether a decorator should be applied to a given service type, such as the current closed generic service type (using the ServiceType property) and the concrete type that will be created (using the ImplementationType property). The predicate will (under normal circumstances) be called only once per generic type, so there is no performance penalty for using it.

Tip: This extension method allows registering decorators that can be applied based on runtime conditions (such as the role of the current user).

Decorators with Func<T> decoratee factories

There are certain scenarios where it is necessary to postpone the building of part of an object graph. For instance when a service needs to control the lifetime of a dependency, needs multiple instances, when instances need to be executed on a different thread, or when instances need to be created within a certain scope or context (e.g. security).

You can easily delay the building of part of the graph by depending on a factory; the factory allows building that part of the object graph to be postponed until the moment the type is actually required. However, when working with decorators, injecting a factory to postpone the creation of the decorated instance will not work. This is best demonstrated with an example.

Take for instance a AsyncCommandHandlerDecorator<T> that executes a command handler on a different thread. We could let the AsyncCommandHandlerDecorator<T> depend on a CommandHandlerFactory<T>, and let this factory call back into the container to retrieve a new ICommandHandler<T> but this would fail, since requesting an ICommandHandler<T> would again wrap the new instance with a AsyncCommandHandlerDecorator<T> and we’d end up recursively creating the same instance type again and again resulting in a stack overflow.

This particular scenario is really hard to solve without library support and as such Simple Injector allows injecting a Func<T> delegate into registered decorators. This delegate functions as a factory for the creation of the decorated instance and avoids the recursive decoration explained above.

Taking the same AsyncCommandHandlerDecorator<T> as an example, it could be implemented as follows:

public class AsyncCommandHandlerDecorator<T> : ICommandHandler<T> {
    private readonly Func<ICommandHandler<T>> decorateeFactory;

    public AsyncCommandHandlerDecorator(Func<ICommandHandler<T>> decorateeFactory) {
        this.decorateeFactory = decorateeFactory;
    }

    public void Handle(T command) {
        // Execute on different thread.
        ThreadPool.QueueUserWorkItem(state => {
            try {
                // Create new handler in this thread.
                ICommandHandler<T> handler = this.decorateeFactory.Invoke();
                handler.Handle(command);
            } catch (Exception ex) {
                // log the exception
            }
        });
    }
}

This special decorator is registered just as any other decorator:

container.RegisterDecorator(
    typeof(ICommandHandler<>),
    typeof(AsyncCommandHandlerDecorator<>),
    c => c.ImplementationType.Name.StartsWith("Async"));

However, in this instance the AsyncCommandHandlerDecorator<T> has only singleton dependencies (Func<T> is a singleton) and creates a new decorated instance each time it’s called so we can register it as a singleton:

container.RegisterSingleDecorator(
    typeof(ICommandHandler<>),
    typeof(AsyncCommandHandlerDecorator<>),
    c => c.ImplementationType.Name.StartsWith("Async"));

Mixing this decorator with other (synchronous) decorators, you’ll have an extremely powerful and pluggable system:

container.RegisterManyForOpenGeneric(
    typeof(ICommandHandler<>),
    typeof(ICommandHandler<>).Assembly);

container.RegisterDecorator(
    typeof(ICommandHandler<>),
    typeof(TransactionCommandHandlerDecorator<>));

container.RegisterDecorator(
    typeof(ICommandHandler<>),
    typeof(DeadlockRetryCommandHandlerDecorator<>));

container.RegisterSingleDecorator(
    typeof(ICommandHandler<>),
    typeof(AsyncCommandHandlerDecorator<>),
    c => c.ImplementationType.Name.StartsWith("Async"));

container.RegisterDecorator(
    typeof(ICommandHandler<>),
    typeof(ValidationCommandHandlerDecorator<>));

This configuration has an interesting mix of decorator registrations.

  1. The registration of the AsyncCommandHandlerDecorator<T> allows (a subset of) command handlers to be executed in the background (while any command handler with a name does not start with ‘Async’ will execute synchronously)
  2. Prior to this point all commands are validated synchronously (to allow communicating validation errors to the caller)
  3. All handlers (sync and async) are executed in a transaction and the operation is retried when the database rolled back because of a deadlock

Another useful application for Func<T> decoratees is when a command needs to be executed in an isolated fashion, e.g. to prevent sharing the unit of work with the request that triggered the execution of that command. This can be achieved by creating a proxy that starts a new lifetime scope, as follows:

using SimpleInjector.Extensions.LifetimeScoping;

public class LifetimeScopeCommandHandlerProxy<T> : ICommandHandler<T> {
    private Container container;
    private readonly Func<ICommandHandler<T>> decorateeFactory;

    public LifetimeScopeCommandHandlerProxy(Container container,
        Func<ICommandHandler<T>> decorateeFactory) {
        this.decorateeFactory = decorateeFactory;
    }

    public void Handle(T command) {
        // Start a new scope.
        using (container.BeginLifetimeScope()) {
            // Create the decorateeFactory within the scope.
            ICommandHandler<T> handler = this.decorateeFactory.Invoke();
            handler.Handle(command);
        });
    }
}

This proxy class starts a new lifetime scope lifestyle and resolves the decoratee within that new scope. The proxy can be registered as follows:

container.RegisterSingleDecorator(
    typeof(ICommandHandler<>),
    typeof(LifetimeScopeCommandHandlerProxy<>));
Note: Since the LifetimeScopeCommandHandlerProxy<T> only depends on singletons (both the Container and the Func<ICommandHandler<T>> are singletons), it too can safely be registered as singleton.

Since a typical application will not use the lifetime scope, but would prefer a scope specific to the application type (such as a web request, web api request or WCF operation lifestyles), a special hybrid lifestyle needs to be defined that allows object graphs to be resolved in this mixed-request scenario:

ScopedLifestyle scopedLifestyle = Lifestyle.CreateHybrid(
    () => container.GetCurrentLifetimeScope() != null,
    trueLifestyle: new LifetimeScopeLifestyle(),
    falseLifestyle: new WebRequestLifestyle());

container.Register<IUnitOfWork, DbUnitOfWork>(hybridLifestyle);

In contrast to the example in hybrid lifestyle section, the hybrid lifestyle defined here prefers the LifetimeScopeLifestyle over the web request lifestyle. This is because the LifetimeScopeCommandHandlerProxy<T> is used to isolate the execution of commands, while letting the code fall back to running on the web request thread when required.

Obviously, if you run (part of) your commands on a background thread and also use registrations with a scoped lifestyle you will have a use for both the LifetimeScopeCommandHandlerProxy<T> and AsyncCommandHandlerDecorator<T> together which can be seen in the following configuration:

var scopedLifestyle = Lifestyle.CreateHybrid(
    () => container.GetCurrentLifetimeScope() != null,
    trueLifestyle: new LifetimeScopeLifestyle(),
    falseLifestyle: new WebRequestLifestyle());

container.Register<IUnitOfWork, DbUnitOfWork>(hybridLifestyle);
container.Register<IRepository<User>, UserRepository>(hybridLifestyle);

container.RegisterManyForOpenGeneric(
    typeof(ICommandHandler<>),
    typeof(ICommandHandler<>).Assembly);

container.RegisterSingleDecorator(
    typeof(ICommandHandler<>),
    typeof(LifetimeScopeCommandHandlerProxy<>));

container.RegisterSingleDecorator(
    typeof(ICommandHandler<>),
    typeof(AsyncCommandHandlerDecorator<>),
    c => c.ImplementationType.Name.StartsWith("Async"));

With this configuration all commands are executed in an isolated context and some are also executed on a background thread.

Decorated collections

When registering a decorator, Simple Injector will automatically decorate any collection with elements of that service type:

container.RegisterAll<IEventHandler<CustomerMovedEvent>>(
    typeof(CustomerMovedEventHandler),
    typeof(NotifyStaffWhenCustomerMovedEventHandler));

container.RegisterDecorator(
    typeof(IEventHandler<>),
    typeof(ValidationEventHandlerDecorator<>),
    c => SomeCondition);

The previous registration registers a collection of IEventHandler<CustomerMovedEvent> services. Those services are decorated with a ValidationEventHandlerDecorator<TEvent> when the supplied predicate holds.

For collections of elements that are created by the container (container controlled), the predicate is checked for each element in the collection. For collections of uncontrolled elements (a list of items that is not created by the container), the predicate is checked once for the whole collection. This means that controlled collections can be partially decorated. Taking the previous example for instance, you could let the CustomerMovedEventHandler be decorated, while leaving the NotifyStaffWhenCustomerMovedEventHandler undecorated (determined by the supplied predicate).

When a collection is uncontrolled, it means that the lifetime of its elements are unknown to the container. The following registration is an example of an uncontrolled collection:

IEnumerable<IEventHandler<CustomerMovedEvent>> handlers =
    new IEventHandler<CustomerMovedEvent>[] {
        new CustomerMovedEventHandler(),
        new NotifyStaffWhenCustomerMovedEventHandler(),
    };

container.RegisterAll<IEventHandler<CustomerMovedEvent>>(handlers);

Although this registration contains a list of singletons, the container has no way of knowing this. The collection could easily have been a dynamic (an ever changing) collection. In this case, the container calls the registered predicate once (and supplies the predicate with the IEventHandler<CusotmerMovedEvent> type) and if the predicate returns true, each element in the collection is decorated with a decorator instance.

Warning: In general you should prevent registering uncontrolled collections. The container knows nothing about them, and can’t help you in doing diagnostics. Since the lifetime of those items is unknown, the container will be unable to wrap a decorator with a lifestyle other than transient. Best practice is to register container-controlled collections which is done by using one of the RegisterAll overloads that take a collection of System.Type instances.

Using contextual information inside decorators

As we shown before, you can apply a decorator conditionally based on a predicate you can supply to the RegisterDecorator overloads:

container.RegisterDecorator(
    typeof(ICommandHandler<>),
    typeof(AsyncCommandHandlerDecorator<>),
    c => c.ImplementationType.Name.StartsWith("Async"));

Sometimes however you might want to apply a decorator unconditionally, but let the decorator act at runtime based on this contextual information. You can do this by injecting the DecoratorContext into the decorator’s constructor as cam be seem in the following example:

public class TransactionCommandHandlerDecorator<T> : ICommandHandler<T> {
    private readonly DecoratorContext decoratorContext;
    private readonly ICommandHandler<T> decoratee;
    private readonly ITransactionBuilder transactionBuilder;

    public TransactionCommandHandlerDecorator(DecoratorContext decoratorContext,
        ICommandHandler<T> decoratee, ITransactionBuilder transactionBuilder) {
        this.decoratorContext = decoratorContext;
        this.decoratee = decoratee;
        this.transactionBuilder = transactionBuilder;
    }

    public void Handle(T command) {
        TransactionType transactionType = this.decoratorContext.ImplementationType
            .GetCustomAttribute<TransactionAttribute>()
            .TransactionType;

        using (var transaction = this.transactionBuilder.BeginTransaction(transactionType)) {
            this.decoratee.Handle(command);
        }
    }
}

The previous code snippet shows a decorator that applies a transaction behavior to command handlers. The decorator is injected with the DecoratorContext class which supplies the decorator with contextual information about the other decorators in the chain and the actual implementation type. In this example the decorator expects a TransactionAttribute to be applied to the wrapped command handler implementation and it starts the correct transaction type based on this information.

If the attribute was applied to the command class instead of the command handler, this decorator would been able to gather this information without the use of the DecoratorContext. This would however leak implementation details into the command, since which type of transaction a handler should run is clearly an implementation detail and is of no concern to the consumer of that command. Placing that attribute on the handler instead of the command is therefore a much more reasonable thing to do.

The decorator would also be able to get the attribute by using the injected decoratee, but this would only work when the decorator would directly wrap the handler. This would make the system quite fragile, since it would break once you start placing other decorator in between this decorator and the handler, which is a very likely thing to happen.

Decorator registration factories

In some advanced scenarios, it can be useful to depend the actual decorator type based on some contextual information. Simple Injector contains a RegisterDecorator overload that accepts a factory delegate that allows building the exact decorator type based on the actual type being decorated.

Take the following registration for instance:

container.RegisterDecorator(
    typeof(IEventHandler<>),
    factoryContext => typeof(LoggingEventHandlerDecorator<,>).MakeGenericType(
        typeof(LoggingEventHandler<,>).GetGenericArguments().First(),
        factoryContext.ImplementationType),
    Lifestyle.Transient,
    predicateContext => true);

This example registers a decorator for the IEventHandler<TEvent> abstraction. The decorator to be used is the LoggingEventHandlerDecorator<TEvent, TLogTarget> type. The supplied factory delegate builds up a partially-closed open-generic type by filling in the TLogTarget argument with the actual wrapped event handler implementation type. Simple Injector will fill in the generic type argument TEvent.

Interception

Interception is the ability to intercept a call from a consumer to a service, and add or change behavior. The decorator pattern describes a form of interception, but when it comes to applying cross-cutting concerns, you might end up writing decorators for many service interfaces, but with the exact same code. If this is happening, it is time to explore the possibilities of interception.

Using the Interception extensions code snippets, you can add the ability to do interception with Simple Injector. Using the given code, you can for instance define a MonitoringInterceptor that allows logging the execution time of the called service method:

private class MonitoringInterceptor : IInterceptor {
    private readonly ILogger logger;

    // Using constructor injection on the interceptor
    public MonitoringInterceptor(ILogger logger) {
        this.logger = logger;
    }

    public void Intercept(IInvocation invocation) {
        var watch = Stopwatch.StartNew();

        // Calls the decorated instance.
        invocation.Proceed();

        var decoratedType = invocation.InvocationTarget.GetType();

        this.logger.Log(string.Format("{0} executed in {1} ms.",
            decoratedType.Name, watch.ElapsedMiliseconds));
    }
}

This interceptor can be registered to be wrapped around a concrete implementation. Using the given extension methods, this can be done as follows:

container.InterceptWith<MonitoringInterceptor>(type => type == typeof(IUserRepository));

This registration ensures that every time an IUserRepository interface is requested, an interception proxy is returned that wraps that instance and uses the MonitoringInterceptor to extend the behavior.

The current example doesn’t add much compared to simply using a decorator. When having many interface service types that need to be decorated with the same behavior however, it gets different:

container.InterceptWith<MonitoringInterceptor>(t => t.Name.EndsWith("Repository"));
Note: The Interception extensions code snippets use .NET’s System.Runtime.Remoting.Proxies.RealProxy class to generate interception proxies. The RealProxy only allows to proxy interfaces.
Note: the interfaces in the given Interception extensions code snippets are a simplified version of the Castle Project interception facility. If you need to create lots different interceptors, you might benefit from using the interception abilities of the Castle Project. Also please note that the given snippets use dynamic proxies to do the interception, while Castle uses lightweight code generation (LCG). LCG allows much better performance than the use of dynamic proxies. Please see this stackoverflow q/a for an implementation for Castle Windsor.
Note: Don’t use interception for intercepting types that all implement the same generic interface, such as ICommandHandler<T> or IValidator<T>. Try using decorator classes instead, as shown in the Decorators section on this page.

Property injection

Simple Injector does not inject any properties into types that get resolved by the container. In general there are two ways of doing property injection, and both are not enabled by default for reasons explained below.

Implicit property injection

Some containers (such as Castle Windsor) implicitly inject public writable properties by default for any instance you resolve. They do this by mapping those properties to configured types. When no such registration exists, or when the property doesn’t have a public setter, the property will be skipped. Simple Injector does not do implicit property injection, and for good reason. We think that implicit property injection is simply too uuhh... implicit :-). Silently skipping properties that can’t be mapped can lead to a DI configuration that can’t be easily verified and can therefore result in an application that fails at runtime instead of failing when the container is verified.

Explicit property injection

We strongly feel that explicit property injection is a much better way to go. With explicit property injection the container is forced to inject a property and the process will fail immediately when a property can’t be mapped or injected. Some containers (such as Unity and Ninject) allow explicit property injection by allowing properties to be decorated with attributes that are defined by the DI library. Problem with this is that this forces the application to take a dependency on the library, which is something that should be prevented.

Because Simple Injector does not encourage its users to take a dependency on the container (except for the startup path of course), Simple Injector does not contain any attributes that allow explicit property injection and it can therefore not explicitly inject properties out-of-the-box.

Besides this, the use of property injection should be very exceptional and in general constructor injection should be used in the majority of cases. If a constructor gets too many parameters (constructor over-injection anti-pattern), it is an indication of a violation of the Single Responsibility Principle (SRP). SRP violations often lead to maintainability issues. So instead of patching constructor over-injection with property injection, the root cause should be analyzed and the type should be refactored, probably with Facade Services. Another common reason to use properties is because those dependencies are optional. Instead of using optional property dependencies, best practice is to inject empty implementations (a.k.a. Null Object pattern) into the constructor.

Enabling property injection

Simple Injector contains two ways to enable property injection. First of all the RegisterInitializer<T> method can be used to inject properties (especially configuration values) on a per-type basis. Take for instance the following code snippet:

container.RegisterInitializer<HandlerBase>(handlerToInitialize => {
    handlerToInitialize.ExecuteAsynchronously = true;
});

In the previous example an Action<T> delegate is registered that will be called every time the container creates a type that inherits from HandlerBase. In this case, the handler will set a configuration value on that class.

Note: although this method can also be used injecting services, please note that the Diagnostic Services will be unable to see and analyze that dependency.

The second way to inject properties is by implementing a custom IPropertySelectionBehavior. The property selection behavior is a general extension point provided by the container, to override the library’s default behavior (which is to not inject properties). The following example enables explicit property injection using attributes, using the ImportAttribute from the System.ComponentModel.Composition.dll:

using System;
using System.ComponentModel.Composition;
using System.Linq;
using System.Reflection;
using SimpleInjector.Advanced;

class ImportPropertySelectionBehavior : IPropertySelectionBehavior {
    public bool SelectProperty(Type type, PropertyInfo prop) {
        return prop.GetCustomAttributes(typeof(ImportAttribute)).Any();
    }
}

The previous class can be registered as follows:

var container = new Container();
container.Options.PropertySelectionBehavior = new ImportPropertySelectionBehavior();

This enables explicit property injection on all properties that are marked with the [Import] attribute and an exception will be thrown when the property cannot be injected for whatever reason.

Tip: Properties injected by the container through the IPropertySelectionBehavior will be analyzed by the Diagnostic Services.
Note: The IPropertySelectionBehavior extension mechanism can also be used to implement implicit property injection. There’s an example of this in the source code. Doing so however is not advised because of the reasons given above.

Covariance and Contravariance

Since version 4.0 of the .NET framework, the type system allows Covariance and Contravariance in Generics (especially interfaces and delegates). This allows for instance, to use a IEnumerable<string> as an IEnumerable<object> (covariance), or to use an Action<object> as an Action<string> (contravariance).

In some circumstances, the application design can benefit from the use of covariance and contravariance (or variance for short) and it would be beneficial when the IoC container returns services that are ‘compatible’ to the requested service, even although the requested service is not registered. To stick with the previous example, the container could return an IEnumerable<string> even when an IEnumerable<object> is requested.

By default, Simple Injector does not return variant implementations of given services, but Simple Injector can be extended to behave this way. The actual way to write this extension depends on the requirements of the application.

Take a look at the following application design around the IEventHandler<in TEvent> interface:

public interface IEventHandler<in TEvent> {
    void Handle(TEvent e);
}

public class CustomerMovedEvent {
    public int CustomerId { get; set; }
    public Address NewAddress { get; set; }
}

public class CustomerMovedAbroadEvent : CustomerMovedEvent {
    public Country Country { get; set; }
}

public class CustomerMovedEventHandler : IEventHandler<CustomerMovedEvent> {
    public void Handle(CustomerMovedEvent e) { ... }
}

The design contains two event classes CustomerMovedEvent and CustomerMovedAbroadEvent (where CustomerMovedAbroadEvent inherits from CustomerMovedEvent) one concrete event handler CustomerMovedEventHandler and a generic interface for event handlers.

We can configure the container in such way that not only a request for IEventHandler<CustomerMovedEvent> results in a CustomerMovedEventHandler, but also a request for IEventHandler<CustomerMovedAbroadEvent> results in that same CustomerMovedEventHandler (because CustomerMovedEventHandler also accepts CustomerMovedAbroadEvents).

There are multiple ways to achieve this. Here’s one:

container.Register<CustomerMovedEventHandler>();

container.RegisterSingleOpenGeneric(typeof(IEventHandler<>),
    typeof(ContravarianceEventHandler<>));

This registration depends on the custom ContravarianceEventHandler<TEvent> that should be placed close to the registration itself:

public sealed class ContravarianceEventHandler<TEvent> : IEventHandler<TEvent> {
    private Registration registration;

    public ContravarianceEventHandler(Container container) {
        // NOTE: GetCurrentRegistrations has a perf characteristic of O(n), so
        // make sure this type is registered as singleton.
        registration = (
            from reg in container.GetCurrentRegistrations()
            where typeof(IEventHandler<TEvent>).IsAssignableFrom(reg.ServiceType)
            select reg)
            .Single();
    }

    void IEventHandler<TEvent>.Handle(TEvent e)
    {
        var handler = (IEventHandler<TEvent>)this.registration.GetInstance();
        handler.Handle(e);
    }
}

The registration ensures that every time an IEventHandler<TEvent> is requested, a ContravarianceEventHandler<TEvent> is returned. The ContravarianceEventHandler<TEvent> will on creation query the container for a single service type that implements the specified IEventHandler<TEvent>. Because the CustomerMovedEventHandler is the only registered event handler for IEventHandler<CustomerMovedEvent>, the ContravarianceEventHandler<CustomerMovedEvent> will find that type and call it.

This is just one example and one way of adding variance support. For a more elaborate discussion on this subject, please read the following article: Adding Covariance and Contravariance to Simple Injector.

Registering plugins dynamically

Applications with a plugin architecture often allow special plugin assemblies to be dropped in a special folder and to be picked up by the application, without the need of a recompile. Although Simple Injector has no out of the box support for this, registering plugins from dynamically loaded assemblies can be implemented in a few lines of code. Here is an example:

string pluginDirectory =
    Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Plugins");

var pluginAssemblies =
    from file in new DirectoryInfo(pluginDirectory).GetFiles()
    where file.Extension.ToLower() == ".dll"
    select Assembly.LoadFile(file.FullName);

var pluginTypes =
    from assembly in pluginAssemblies
    from type in assembly.GetExportedTypes()
    where typeof(IPlugin).IsAssignableFrom(type)
    where !type.IsAbstract
    where !type.IsGenericTypeDefinition
    select type;

container.RegisterAll<IPlugin>(pluginTypes);

The given example makes use of an IPlugin interface that is known to the application, and probably located in a shared assembly. The dynamically loaded plugin .dll files can contain multiple classes that implement IPlugin, and all publicly exposed concrete types that implements IPlugin will be registered using the RegisterAll method and can get resolved using the default auto-wiring behavior of the container, meaning that the plugin must have a single public constructor and all constructor arguments must be resolvable by the container. The plugins can get resolved using container.GetAllInstances<IPlugin>() or by adding an IEnumerable<IPlugin> argument to a constructor.