Windsor can take full advantage of underlying power of Castle DynamicProxy
to offer interesting capabilities.
Learn more about DynamicProxy
It is very valuable when using features described here, to have good understanding of how DynamicProxy works and its limitations. See DynamicProxy documentation here
How to create a proxy
You don't have to specify explicitly that you want your component to be a proxy. Windsor will create proxy of the component if any of the following is true:
- There are interceptors specified for that component (that includes interceptors selected dynamically via model interceptors selectors)
- There are mixins specified for that component
- There are additional interfaces specified for that component
There may be also other cases when any of these conditions becomes true indirectly. For example Typed Factory Facility
works by creating proxies implicitly. Other facilities are also free to modify your components so that they will be proxied.
You can specify interceptors and other proxy options for components in three ways:
If you want to explicitly associate interceptor with a component you can do it with
public interface IOrderRepository
Order GetOrder(Guid id);
public class OrderRepository: IOrderRepository
Order GetOrder(Guid id)
// some implementation
Few things to note about the attribute:
- You put it on component class, not interface.
- You can specify multiple interceptors by putting multiple attributes on the class.
- You can specify interceptors either by type or by name.
InterceptorAttribute and classes
is defined in a way that allows you to put it not only on classes, but on any other target where custom attribute is allowed, like interface or a method. However Windsor will ignore the attribute unless it's on component's implementation class.
This permissive behavior was introduced to allow people to add support for other targets by building custom extensions.
In order to use interceptors you have to register them in the container just like any other services.
When you then resolve
Windsor will first create a proxy, and use the two interceptors to intercept calls to its members.
Make interceptors transient
It is strongly advised that you always make your interceptors transient. Since interceptors can intercept multiple components with various lifestyles it's best if their own lifespan is no longer than the component they intercept. So unless you have a very good reason not to, always make them transient.
Sometimes in order to function properly interceptor needs not just the information from the
but also from the
of the component it is intercepting.
For example it wants to cache some information about the component upfront before intercepting any call, or it needs some information from extended properties of the component in order to do its job.
In such cases interceptors should implement the
interface, which has just single method.
void SetInterceptedComponentModel(ComponentModel target);
When instantiating the interceptor and attaching it to the component, Windsor will then look if any of the interceptors selected for the component implements
, and for all that do, it will invoke its
of the component being created.
You can specify mixins using either fluent API or XML configuration.
When mixing components keep in mind their lifestyle. Same rules apply as when building direct dependencies between components. That's why it's best if lifestyles of mixed components match.
You can specify additional interfaces using either fluent API or XML configuration.