Note: this documentation is specific for Simple Injector version 2.0 and up. Look here for 1.x specific documentation.

Advanced scenarios with Simple Injector

Although its name might not indicate it, Simple Injector is capable of handling many advanced scenarios. Sometimes by writing some custom code, taking code from this wiki, or by using the extension points from the SimpleInjector.Extensions namespace of the core library.

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

Batch registration / Automatic registration

Batch registration or automatic registration is a way to register a set of related types based on some convention. This saves you from registering each type explicitly and lowers the amount of maintenance on your configuration. The following example show a set of manual 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 configuration too often, we can use the non-generic registration overloads, combined 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 DI frameworks contain an advanced API for doing convention based registration, we found that doing this with custom LINQ queries is often easier to write, easier to understand, and even more flexible than using such an API.

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

public interface IValidator<T>
{
    ValidationResults Validate(T instance);
}
Your application might contain many implementations of this interface, for instance for validating customers, employees, orders, products, etc. You would normally end up with a registration as we've seen before:

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...
Using the extension methods for batch registration of open generic types from the SimpleInjector.Extesions namespace however, you can write it down to a single line:

container.RegisterManyForOpenGeneric(typeof(IValidator<>),
    typeof(IValidator<>).Assembly);
This call searches the supplied assembly for all public types that implement the IValidator<T> interface and it 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 RegisterManyForOpenGeneric overloads available that take a list of System.Type instances, instead a list of Assembly instances.
This however is just one example of what you can do using batch registration. A more advanced scenario is the registration of multiple implementations of the same closed generic type to a single interface. Because there are many possible variations of this scenario, Simple Injector does not contain any methods to do this. It does contain however, multiple overloads of the RegisterManyForOpenGeneric that allows you to supply a callback delegate that lets you do the registration yourself. Take for instance the scenario where you have a CustomerValidator and a GoldCustomerValidator type, that each implement IValidator<Customer>, and you want to register both of them. The previous registration would throw an exception telling you that you have multiple types implementing the same closed generic type. The following registration however, does enable this scenario:

container.RegisterManyForOpenGeneric(typeof(IValidator<>),
    AccessibilityOption.PublicTypesOnly,
    (serviceType, implTypes) => container.RegisterAll(serviceType, implTypes),
    typeof(IValidator<>).Assembly);
The previous code snippet registers all types from the given assembly that implement IValidatore<T> and it registers them as a collection of instances. In other words, with the given example, IValidator<T> instances can be retrieved by calling container.GetAllInstances<IValidator<T>>() or by using an IEnumerable<IValidator<T>> argument in a constructor.

Do note that using an IEnumerable<IValidator<T>> dependency in your constructor or calling into the container directly, are generally not recommended approaches. Depending on a collection of types complicates your application design, and can often be simplified with the right configuration of your container. Your constructors should simply depend on a single IValidator<T>. In this case, a better solution would therefore be to create and inject 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.RegisterSingleOpenGeneric(typeof(IValidate<>), 
    typeof(CompositeValidator<>));
This 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 fact you should not see the the injected IEnumerable<IValidator<T>> as a collection, but merely a stream. Simple Injector will always inject a reference to the same stream (the IEnumerable<T> itself is a Singleton), but every time you iterate this IEnumerable<T>, for each individual component, the container is asked to resolve an instance based on the lifestyle that component. This means that even though the CompositeValidator<T> is registered as singleton, the validators it wraps can still have their own lifestyle.
The next section will explain mapping of open generic types, as the one we've just seen.

Registration of open generic types

When working with generic interfaces, we will often see many 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, because it is very likely that not all entities will need validation. Still we would like to prevent from having to write an empty validation class per entity or having to write special application logic to check if an entity has validation. In this situation, we will probably want to use the registration as described in the previous section, and fall back to returning the default implementation when no such registration exists for a given type. Such default implementation could look like this, for instance:

// Implementation of the Null Object pattern.
class NullValidator<T> : IValidate<T> {
    public ValidationResults Validate(T instance) {
        return ValidationResults.Valid;
    }
}
We can use this NullValidator<T> for all entities that don't 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 is of course not very practical. Falling back to such a default implementation is a typical scenario for unregistered type resolution. Simple Injector contains an event that you can hook to that allows to fall back to a default implementation. On top of this event, the RegisterOpenGeneric extension method available. The given situation would be implemented as follows:

// using SimpleInjector.Extensions;
container.RegisterSingleOpenGeneric(
    typeof(IValidate<>), 
    typeof(NullValidator<>));
The result of this registration is that for instance a single NullValidator<Department> instance is returned every time an IValidate<Department> is requested.

Note: Because the use of unregistered type resolution, a NullValidator<T> will only get returned for types that are not registered, therefore allowing the default implementation to be overridden for a specific implementation. The RegisterManyForOpenGeneric method, for instance, doesn’t use unregistered type resolution, but simply registers all concrete types it finds in the given assemblies. Those types will therefore always be returned, giving a very convenient and easy to grasp mix.

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 framework 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 frameworks 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 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 {
    private readonly IServiceProvider container;
    
    public DataAnnotationsValidator(Container container) {
        this.container = container;
    }
    
    void IValidator.ValidateObject(object instance) {
        var context = new ValidationContext(instance,
            this.container, null);

        // Throws an exception when instance is invalid.
        Validator.ValidateObject(instance, context);    
    }
}
The implementations of the ICommandHandler<T> interface can be registered using the RegisterManyForOpenGeneric extension method:

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 implication 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> factories

In certain scenarios, it is needed to postpone building part of the 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 in a certain scope or (security) context.

When building a 'normal' object graph with dependencies, you can easily delay building a part of the graph by letting a service depend on a factory. This allows building that part of the object graph to be postponed until the time the type starts using the factory. When working with decorators however, injecting a factory to postpone the creation of the decorated instance will not work. Take for instance a AsyncCommandHandlerDecorator<T> that allows executing 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>. Unfortunately this would fail, since requesting an ICommandHandler<T> would again wrap this instance with a new AsyncCommandHandlerDecorator<T>, and we'd end up recursively creating the same instance and causing a stack overflow.

Since this is a scenario that is really hard to solve without framework support, Simple Injector allows injecting a Func<T> delegate into registered decorators. This delegate functions as a factory for the creation of the decorated instance. Taking the AsyncCommandHandlerDecorator<T> as example, it could be implemented as follows:

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

    public AsyncCommandHandlerDecorator(
        Func<ICommandHandler<T>> factory) {
        this.factory = factory;
    }
    
    public void Handle(T command) {
        // Execute on different thread.
        ThreadPool.QueueUserWorkItem(_ => {
            // Create new handler in this thread.
            var handler = this.factory();
            handler.Handle(command)
        });
    }
}
This special decorator can be registered just as any other decorator:

container.RegisterDecorator(
    typeof(ICommandHandler<>),
    typeof(AsyncCommandHandlerDecorator<>),
    c => c.ImplementationType.Name.StartsWith("Async"));
However, since the AsyncCommandHandlerDecorator<T> solely has singleton dependencies (the Func<T> is a singleton), and creates a new decorated instance each time it’s called, we can even register it as a singleton itself:

container.RegisterSingleDecorator(
    typeof(ICommandHandler<>),
    typeof(AsyncCommandHandlerDecorator<>),
    c => c.ImplementationType.Name.StartsWith("Async"));
When mixing this with other (synchronous) decorators, you'll get 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. The registration of the AsyncCommandHandlerDecorator<T> allows (some of) the command handlers to be executed on the background (while others -who's name does not start with 'Async'- still run synchronously), but before execution, all commands are validated synchronously (to allow communicating validation errors to the caller). And all handlers (even the asynchronous ones) are executed in a transaction and the operation is retried when the database rolled back because of a deadlock).

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.

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.
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 framework. Problem with this is that this forces the application to take a dependency on the framework, 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) {
        registration = (
            from reg in container.GetCurrentRegistrations()
            where typeof(IEventHandler<TEvent>)
                .IsAssignableFrom(reg.ServiceType)
            select reg)
            .Single();

        this.handlerFactory =() => 
            (IEventHandler<TEvent>)registration.GetInstance();
    }

    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.





























Resolving instances by key

The information you are looking for has been moved. Please see the Resolve Instances By Key section of the How to documentation page, for the information you are looking for.




Resolving array and lists

The information you are looking for has been moved. Please see the Resolve Arrays and Lists section of the How to page, for the information you are looking for.




Lifetime scoping

The information you are looking for has been moved. Please see the Per Lifetime Scope section of the Object Lifestyle Management documentation page for more information.














Last edited Apr 10 at 2:02 PM by dot_NET_Junkie, version 60