ContainerRegisterDecorator Method (Type, FuncDecoratorPredicateContext, Type, Lifestyle, PredicateDecoratorPredicateContext)

Simple Injector
Ensures that the decorator type that is returned from decoratorTypeFactory is supplied when the supplied predicate returns true and cached with the given lifestyle, wrapping the original registered serviceType, by injecting that service type into the constructor of the decorator type that is returned by the supplied decoratorTypeFactory. Multiple decorators may be applied to the same serviceType. Decorators can be applied to both open, closed, and non-generic service types.

Namespace:  SimpleInjector
Assembly:  SimpleInjector (in SimpleInjector.dll) Version: 5.3.0

public void RegisterDecorator(
	Type serviceType,
	Func<DecoratorPredicateContext, Type> decoratorTypeFactory,
	Lifestyle lifestyle,
	Predicate<DecoratorPredicateContext> predicate


Type: SystemType
The definition of the (possibly open generic) service type that will be wrapped by the decorator type that is returned from decoratorTypeFactory.
Type: SystemFuncDecoratorPredicateContext, Type
A factory that allows building Type objects that define the decorators to inject, based on the given contextual information. The delegate is allowed to return (partially) open-generic types.
Type: SimpleInjectorLifestyle
The lifestyle that specifies how the returned decorator will be cached.
Type: SystemPredicateDecoratorPredicateContext
The predicate that determines whether the decorator must be applied to a service type.

ArgumentNullExceptionThrown when one of the arguments is a null reference.

The types returned from the decoratorTypeFactory may be non-generic, closed-generic, open-generic and even partially-closed generic. The container will try to fill in the generic parameters based on the resolved service type.

The RegisterDecorator method works by hooking onto the container's ExpressionBuilt event. This event fires after the ResolveUnregisteredType event, which allows decoration of types that are resolved using unregistered type resolution.

Multiple decorators can be applied to the same service type. The order in which they are registered is the order they get applied in. This means that the decorator that gets registered first, gets applied first, which means that the next registered decorator, will wrap the first decorator, which wraps the original service type.

Constructor injection will be used on that type, and although it may have many constructor arguments, it must have exactly one argument of the type of serviceType, or an argument of type FuncTResult where TResult is serviceType. An exception will be thrown when this is not the case.

The type returned from decoratorTypeFactory may have a constructor with an argument of type FuncTResult where T is serviceType. In this case, the library will not inject the decorated serviceType itself into the decorator instance, but it will inject a FuncTResult that allows creating instances of the decorated type, according to the lifestyle of that type. This enables more advanced scenarios, such as executing the decorated types on a different thread, or executing decorated instance within a certain scope (such as a lifetime scope).


The following is an example of the registration of a decorator through the factory delegate:
container.Register<ICommandHandler<MoveCustomerCommand>, MoveCustomerCommandHandler>();

    context => typeof(LoggingCommandHandler<,>).MakeGenericType(
    context => true);

var handler = container.GetInstance<ICommandHandler<MoveCustomerCommand>>();

    typeof(LoggingCommandHandler<MoveCustomerCommand, MoveCustomerCommandHandler>));
The code above allows a generic LoggingCommandHandler<TCommand, TImplementation> to be applied to command handlers, where the second generic argument will be filled in using the contextual information.
See Also