=========================== Aspect-Oriented Programming =========================== 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 chance of breaking existing code much smaller and prevent having to make sweeping changes throughout the code base. This way of working is often referred to as aspect-oriented programming. Aspect-oriented programming (AOP) is a programming paradigm that aims to increase modularity by allowing the separation of cross-cutting concerns. It allows new behavior to be plugged in or changed, without having to change or even recompile existing code. Simple Injector's main support for AOP is by the use of decorators. Besides decorators, one can also plugin interception using a dynamic proxy framework. This chapter discusses the following subjects: * :ref:`Decoration ` * :ref:`Interception using Dynamic Proxies ` .. _Decoration: Decoration ========== The best way 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 :ref:`Registration of open generic types ` section or for instance the use of an generic *ICommandHandler* interface. .. container:: Note **Tip**: `This article `_ describes an architecture based on the use of the *ICommandHandler* interface. Take the plausible scenario where you want to validate all commands that get executed by an *ICommandHandler* implementation. The Open/Closed principle states that you want to do this without having to alter each and every implementation. You can achieve this using a (single) decorator: .. code-block:: c# public class ValidationCommandHandlerDecorator : ICommandHandler { private readonly IValidator validator; private readonly ICommandHandler decoratee; public ValidationCommandHandlerDecorator( IValidator validator, ICommandHandler decoratee) { this.validator = validator; this.decoratee = decoratee; } void ICommandHandler.Handle(TCommand command) { // validate the supplied command (throws when invalid). this.validator.ValidateObject(command); // forward the (valid) command to the real command handler. this.decoratee.Handle(command); } } The *ValidationCommandHandlerDecorator* class is an implementation of the *ICommandHandler* interface, but it also wraps / decorates an *ICommandHandler* instance. Instead of injecting the real implementation directly into a consumer, you can (let Simple Injector) inject a validator decorator that wraps the real implementation. The *ValidationCommandHandlerDecorator* depends on an *IValidator* interface. An implementation that used Microsoft Data Annotations might look like this: .. code-block:: c# 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* interface can be registered using the **Register** method overload that takes in a list of assemblies: .. code-block:: c# container.Register(typeof(ICommandHandler<>), typeof(ICommandHandler<>).Assembly); By using the following method, you can wrap the *ValidationCommandHandlerDecorator* around each and every *ICommandHandler* implementation: .. code-block:: c# container.RegisterDecorator( typeof(ICommandHandler<>), typeof(ValidationCommandHandlerDecorator<>)); Multiple decorators can be wrapped by calling the **RegisterDecorator** method multiple times, as the following registration shows: .. code-block:: c# container.Register(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* in this case) wraps the real instance, the second decorator (*DeadlockRetryCommandHandlerDecorator* in this case) wraps the first decorator, and so on. .. container:: Note **Tip**: Are the previous three decorators applied in the correct order? `This GitHub issue `_ gives more insights into this. .. _Applying-decorators-conditionally: Applying Decorators conditionally --------------------------------- 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: .. code-block:: c# container.RegisterDecorator( typeof(ICommandHandler<>), typeof(AccessValidationCommandHandlerDecorator<>), context => typeof(IAccessRestricted).IsAssignableFrom( context.ServiceType.GetGenericArguments()[0])); 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 closed-generic type, so there is no performance penalty for using it. .. _Applying-decorators-conditionally-using-type-constraints: Applying Decorators conditionally using type constraints -------------------------------------------------------- The previous example shows the conditional registration of the *AccessValidationCommandHandlerDecorator* decorator. It is applied in case the closed *TCommand* type (of *ICommandHandler*) implements the *IAccessRestricted* interface. Simple Injector will automatically apply decorators conditionally based on defined `generic type constraints `_. You can, therefore, define the *AccessValidationCommandHandlerDecorator* with a generic type constraint: .. code-block:: c# class AccessValidationCommandHandlerDecorator : ICommandHandler where TCommand : IAccessRestricted { private readonly ICommandHandler decoratee; public AccessValidationCommandHandlerDecorator(ICommandHandler decoratee) { this.decoratee = decoratee; } void ICommandHandler.Handle(TCommand command) { // Do access validation this.decoratee.Handle(command); } } Because Simple Injector natively understands generic type constraints, you can reduce the previous registration to the following: .. code-block:: c# container.RegisterDecorator( typeof(ICommandHandler<>), typeof(AccessValidationCommandHandlerDecorator<>)); The use of generic type constraints has many advantages: * It allows constraints to be specified exactly once, in the place it often makes most obvious, i.e. the decorator itself. * It allows constraints to be specified in the syntax you are used to the most, i.e. C#. * It allows constraints to be specified in a very succinct manner compared to the verbose, error prone and often hard to read syntax of the reflection API (the previous examples already shown this). * It allows decorator to be simplified, because of the added compile time support. Obviously there are cases where these conditions can't or shouldn't be defined using generic type constraints. The following code example shows a registration that can't be expressed using generic type constraints: .. code-block:: c# container.RegisterDecorator( typeof(ICommandHandler<>), typeof(AccessValidationCommandHandlerDecorator<>), c => c.ImplementationType.GetCustomAttributes(typeof(AccessAttribute)).Any()); This registration applies the decorator conditionally based on an attribute on the (initially) decorated handler type. There is obviously no way to express this using generic type constraints, so you will have to fallback to the predicate syntax. .. _Decorators-with-Func-factories: Decorators with Func 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 :ref:`executed on a different thread `, or when instances need to be created within a certain :ref:`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 an *AsyncCommandHandlerDecorator* that executes a command handler on a different thread. You could let the *AsyncCommandHandlerDecorator* depend on a *CommandHandlerFactory*, and let this factory call back into the container to retrieve a new *ICommandHandler* but this would fail, because requesting an *ICommandHandler* would again wrap the new instance with a *AsyncCommandHandlerDecorator* and you'd end up recursively creating the same instance type again and again resulting in an endless loop. This particular scenario is really hard to solve without library support and as such Simple Injector allows injecting a *Func* 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* as an example, it could be implemented as follows: .. code-block:: c# public class AsyncCommandHandlerDecorator : ICommandHandler { private readonly Func> decorateeFactory; public AsyncCommandHandlerDecorator(Func> decorateeFactory) { this.decorateeFactory = decorateeFactory; } public void Handle(T command) { // Execute on different thread. ThreadPool.QueueUserWorkItem(state => { try { // Create new handler in this thread. ICommandHandler handler = this.decorateeFactory.Invoke(); handler.Handle(command); } catch (Exception ex) { // log the exception } }); } } This special decorator is registered just as any other decorator: .. code-block:: c# container.RegisterDecorator( typeof(ICommandHandler<>), typeof(AsyncCommandHandlerDecorator<>), c => c.ImplementationType.Name.StartsWith("Async")); The *AsyncCommandHandlerDecorator* however, has only singleton dependencies (the *Func* is a singleton) and the *Func>* factory always calls back into the container to register a decorated instance conforming the decoratee's lifestyle, each time it's called. If, for instance, the decoratee is registered as transient, each call to the factory will result in a new instance. It is, therefore, safe to register this decorator as a singleton: .. code-block:: c# container.RegisterDecorator( typeof(ICommandHandler<>), typeof(AsyncCommandHandlerDecorator<>), Lifestyle.Singleton, c => c.ImplementationType.Name.StartsWith("Async")); When mixing this decorator with other (synchronous) decorators, you'll get an extremely powerful and pluggable system: .. code-block:: c# container.Register(typeof(ICommandHandler<>), typeof(ICommandHandler<>).Assembly); container.RegisterDecorator( typeof(ICommandHandler<>), typeof(TransactionCommandHandlerDecorator<>)); container.RegisterDecorator( typeof(ICommandHandler<>), typeof(DeadlockRetryCommandHandlerDecorator<>)); container.RegisterDecorator( typeof(ICommandHandler<>), typeof(AsyncCommandHandlerDecorator<>), Lifestyle.Singleton, 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* allows (a subset of) command handlers to be executed in the background (while any command handler with a name that does not start with 'Async' will execute synchronously) #. Prior to this point all commands are validated synchronously (to allow communicating validation errors to the caller) #. All handlers (sync and async) are executed in a transaction and the operation is retried when the database rolled back because of a deadlock .. container:: Note **Warning**: Please note that the previous example is just meant for educational purposes. In practice, you don't want your commands to be processed this way, because it could lead to message loss. Instead you want to use a durable queue. Another useful application for *Func* decoratee factories 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 operation-specific scope, as follows: .. code-block:: c# using SimpleInjector.Lifestyles; public class ScopedCommandHandlerProxy : ICommandHandler { private readonly Container container; private readonly Func> decorateeFactory; public ScopedCommandHandlerProxy( Container container, Func> decorateeFactory) { this.container = container; this.decorateeFactory = decorateeFactory; } public void Handle(T command) { // Start a new scope. using (AsyncScopedLifestyle.BeginScope(container)) { // Create the decorateeFactory within the scope. ICommandHandler handler = this.decorateeFactory.Invoke(); handler.Handle(command); }; } } This proxy class starts a new :ref:`async-scoped lifestyle ` and resolves the decoratee within that new scope using the factory. The use of the factory ensures that the decoratee is resolved according to its lifestyle, independent of the lifestyle of the proxy class. The proxy can be registered as follows: .. code-block:: c# container.RegisterDecorator( typeof(ICommandHandler<>), typeof(ScopedCommandHandlerProxy<>), Lifestyle.Singleton); .. container:: Note **Note**: Because the *ScopedCommandHandlerProxy* only depends on two singletons (both the *Container* and the *Func>* are singletons), it too can safely be registered as singleton. If you run (part of) your commands on a background thread and also use registrations with a :ref:`scoped lifestyle ` you will have a use both the *ScopedCommandHandlerProxy* and *AsyncCommandHandlerDecorator* together which can be seen in the following configuration: .. code-block:: c# container.Options.DefaultScopedLifestyle = new AsyncScopedLifestyle(); container.Register(Lifestyle.Scoped); container.Register, UserRepository>(Lifestyle.Scoped); container.Register(typeof(ICommandHandler<>), typeof(ICommandHandler<>).Assembly); container.RegisterDecorator( typeof(ICommandHandler<>), typeof(ScopedCommandHandlerProxy<>), Lifestyle.Singleton); container.RegisterDecorator( typeof(ICommandHandler<>), typeof(AsyncCommandHandlerDecorator<>), Lifestyle.Singleton, 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: Decorated collections --------------------- When registering a decorator, Simple Injector will automatically decorate any collection with elements of that service type: .. code-block:: c# container.Collection.Register>( typeof(CustomerMovedEventHandler), typeof(NotifyStaffWhenCustomerMovedEventHandler)); container.RegisterDecorator( typeof(IEventHandler<>), typeof(TransactionEventHandlerDecorator<>), c => SomeCondition); The previous registration registers a collection of *IEventHandler* services. Those services are decorated with a *TransactionEventHandlerDecorator* when the supplied predicate holds. .. container:: Note **Note**: Collections in Simple Injector behave as **streams**. Please see the section about :ref:`collection types ` for more information. 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 only 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: .. code-block:: c# IEnumerable> handlers = new IEventHandler[] { new CustomerMovedEventHandler(), new NotifyStaffWhenCustomerMovedEventHandler(), }; container.Collection.Register>(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* type) and if the predicate returns true, each element in the collection is decorated with a decorator instance. .. container:: Note **Warning**: In general you should prevent registering uncontrolled collections. The container knows nothing about them, and can't help you in doing :doc:`diagnostics `. With the lifetime of those items 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 **Collection.Register** overloads that take a collection of *System.Type* instances. .. _Using-contextual-information-inside-decorators: 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: .. code-block:: c# 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 a **DecoratorContext** into the decorator's constructor as can be seem in the following example: .. code-block:: c# public class TransactionCommandHandlerDecorator : ICommandHandler { private readonly ITransactionBuilder builder; private readonly ICommandHandler decoratee; private readonly TransactionType transactionType; public TransactionCommandHandlerDecorator( DecoratorContext decoratorContext, ITransactionBuilder builder, ICommandHandler decoratee) { this.builder = builder; this.decoratee = decoratee; this.transactionType = decoratorContext.ImplementationType .GetCustomAttribute() .TransactionType; } public void Handle(T command) { using (var ta = this.builder.BeginTransaction(this.transactionType)) { this.decoratee.Handle(command); ta.Complete(); } } } 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. The following code snippet shows a possible command handler implementation: .. code-block:: c# [Transaction(TransactionType.ReadCommitted)] public class ShipOrderHandler : ICommandHandler { public void Handle(ShipOrder command) { // Business logic here } } 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—which type of transaction a handler should run is an implementation detail and is of no concern to the consumers 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 if the decorator would directly wrap the handler. This would make the system quite fragile, as it would break once you start placing other decorator in between this decorator and the handler, which is a likely thing to happen. .. _Applying-decorators-conditionally-based-on-consumer: Applying decorators conditionally based on consumer --------------------------------------------------- The previous examples showed how to apply a decorator conditionally based on information about its dependencies, such as the decorators that it wraps and the wrapped real implementation. Another option is to make decisions based on the consuming components; the components the decorator is injected into. Although the **RegisterDecorator** methods don't have any built-in support for this, this behavior can be achieved by using the **RegisterConditional** methods. For instance: .. code-block:: c# container.RegisterConditional( c => c.Consumer.ImplementationType == typeof(UserController)); container.RegisterConditional( c => c.Consumer.ImplementationType == typeof(EmailBatchProcessor)); container.RegisterConditional(c => !c.Handled); Here you use **RegisterConditional** to register two decorators. Both decorator will wrap the *SmtpMailSender* that is registered last. The *AsyncMailSenderDecorator* is wrapped around the *SmtpMailSender* in case it is injected into the *UserController*, while the *BufferedMailSenderDecorator* is wrapped when injected into the *EmailBatchProcessor*. Note that the *SmtpMailSender* is registered as conditional as well, and is registered as fallback registration using `!c.Handled`. This basically means that in case no other registration applies, that registration is used. .. _Decorator-registration-factories: Decorator registration factories -------------------------------- In some advanced scenarios, it can be useful to depend the actual decorator type based on some contextual information. There is 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: .. code-block:: c# container.RegisterDecorator( typeof(IEventHandler<>), factoryContext => typeof(LoggingEventHandlerDecorator<,>).MakeGenericType( typeof(LoggingEventHandler<,>).GetGenericArguments().First(), factoryContext.ImplementationType), Lifestyle.Transient, predicateContext => true); In this example you register the *LoggingEventHandlerDecorator* decorator for the *IEventHandler* abstraction. The supplied factory delegate builds up a partially closed generic type by filling in the *TLogTarget* argument, where the *TEvent* is left 'open'. This is done by requesting the first generic type argument (the *TEvent*) from the open-generic *LoggingEventHandler<,>* type itself and using the **ImplementationType** as second argument. This means that when this decorator is wrapped around a type called *CustomerMovedEventHandler*, the factory method will create the type *LoggingEventHandler*. In other words, the second argument is a concrete type (and thus closed), while the first argument is still a blank. When a closed version of *IEventHandler* is requested later on, Simple Injector will know how to fill in the blank with the correct type for this *TEvent* argument. .. container:: Note **Tip**: Simple Injector doesn't care in which order you define your generic type arguments, nor how you name them—it will be able to figure out the correct type to build any way. .. container:: Note **Note**: The type factory delegate is typically called once per closed type and the result is burned in the compiled object graph. You can't use this delegate to make runtime decisions. .. _Applying-lifestyles-to-Decorators: Applying lifestyles to Decorators --------------------------------- Just as with any other registration, lifestyles can be applied to decorators. The following code snippet demonstrates this: .. code-block:: c# container.Register(Lifestyle.Singleton); container.RegisterDecorator( Lifestyle.Singleton); The following code listing shows the definitions of *SmtpMessageSender* and *AsyncMessageSenderDecorator*: .. code-block:: c# class SmtpMessageSender : IMessageSender { public void Send(string message) { ... } } class AsyncMessageSenderDecorator : IMessageSender { private readonly IMessageSender decoratee; public AsyncMessageSenderDecorator(IMessageSender decoratee) { this.decoratee = decoratee; } public void Send(string message) { ... } } In this example, when *IMessageSender* is resolved, Simple Injector ensures that the same *AsyncMessageSenderDecorator* instance is always returned, which will reference the *SmtpMessageSender* instance. But Simple Injector does not always guarantee that a **Singleton** decorator will only have one instance—and for good reason, which we'll explain below. .. container:: Note **Warning**: Lifestyles applied to decorators do not have the same uniqueness characteristics as with normal registrations. Lifestyles are applied to the decorator in combination with the wrapped service. Consider the following variation of the previous code sample, but where there is not one *IMessageSender*, but instead a collection of *IMessageSender* components: .. code-block:: c# container.Collection.Append(Lifestyle.Singleton); container.Collection.Append(Lifestyle.Singleton); container.RegisterDecorator( Lifestyle.Singleton); In this case, the two implementations *SmtpMessageSender* and *SmsMessageSender* are registered as part of a collection of *IMessageSender* services. In this case, even though *AsyncMailSenderDecorator* is registered as **Singleton**, two decorator instances will exist: one that wraps *SmtpMessageSender* and one that wraps *SmsMessageSender*. Consider what would have happened if Simple Injector would guarantee that only one *AsyncMailSenderDecorator* was ever created. As one *AsyncMailSenderDecorator* instance could only reference one single *IMessageSender*, Simple Injector would have to choose whether to inject *SmtpMessageSender* or *SmsMessageSender*, neither which is correct, because that would remove the other service from the collection. Making *AsyncMailSenderDecorator* truly unique would, therefore, cause Simple Injector to return a collection that would be shaped as follows: .. code-block:: c# var decorator = new AsyncMailSenderDecorator(new SmtpMessageSender()); // Two elements in the collection, so decorator should be returned twice. return IMessageSender[] { decorator, decorator }; Instead, you would expect the collection to be shaped as follows (which is what Simple Injector actually does): .. code-block:: c# var decorator1 = new AsyncMailSenderDecorator(new SmtpMessageSender()); var decorator2 = new AsyncMailSenderDecorator(new SmsMessageSender()); return IMessageSender[] { decorator1, decorator2 }; What this means is that Simple Injector will guarantee uniqueness of a decorator, but this uniqueness is not global, but rather local to a specific registration. .. _Interception-using-Dynamic-Proxies: .. _Interception: Interception using Dynamic Proxies ================================== 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's time to take a close look at your design. If, for what ever reason, it's impossible for you to make the required improvements to your design, your second best bet is to explore the possibilities of *Dynamic Interception* through dynamic proxies. .. container:: Note **Warning**: Simple Injector has :ref:`no out-of-the-box support for interception ` because the use of interception is an indication of a sub-optimal design and we are keen on pushing developers into best practices. Whenever possible, choose to improve your design to make decoration possible. Using the :doc:`Interception extensions ` code snippets, you can add the ability to do dynamic 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: .. code-block:: c# 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: .. code-block:: c# container.InterceptWith(type => type == typeof(IUserRepository)); This registration ensures that every time an *IUserRepository* interface is requested, a 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: .. code-block:: c# container.InterceptWith(t => t.Name.EndsWith("Repository")); .. container:: Note **Note**: The :doc:`Interception extensions ` code snippets use .NET's *System.Runtime.Remoting.Proxies.RealProxy* class to generate interception proxies. The *RealProxy* only allows to proxy interfaces. .. container:: Note **Note**: the interfaces in the given :doc:`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. .. container:: Note **Note**: Don't use dynamic interception for intercepting types that all implement the same generic interface, such as *ICommandHandler* or *IValidator*. Try using decorator classes instead, as shown in the :ref:`Decoration ` section on this page.