|
DynamicProxy2
DynamicProxy2 can be used with Autofac for AOP functionality
Autofac2 IntroductionDynamicProxy2, from the Castle Project, provides a method interception framework. The AutofactContrib DynamicProxy2 integration enables method calls on Autofac components to be intercepted by other components. Common use-cases are transaction handling, logging, and declarative security. Required References
UsageIn Autofac2's DP2 integration, the component to be intercepted must be marked at registration time: var builder = new ContainerBuilder();
builder.RegisterType<C>().As<IHasI>()
.EnableInterfaceInterceptors();
builder.RegisterType<AddOneInterceptor>();
var cpt = builder.Build().Resolve<IHasI>(); The two options available are EnableInterfaceInterceptors(), which creates additional interface proxy objects to do interception, and EnableClassInterceptors(), which dynamically subclasses the target component to perform interception of virtual methods. Both techniques can be used in conjunction with the new assembly scanning support, so you can configure batches of components using the same methods. Inteceptors can be applied using attributes as in the previous version, for example: [Intercept(typeof(AddOneInterceptor))]
public interface IHasI
{
int GetI();
} Some examples of usage can be found in the test cases here: Alternatively, interceptors can be associated with a type at registration time: builder.RegisterType<CustomerService>()
.As<ICustomerService>()
.EnableInterfaceInterceptors()
.InterceptedBy(typeof(AddOneInterceptor)); This is further demonstrated here: InterceptorsInterceptors implement the DynamicProxy IInterceptor interface: public class CallLogger : IInterceptor
{
TextWriter _output;
public CallLogger(TextWriter output)
{
_output = output;
}
public void Intercept(IInvocation invocation)
{
_output.Write("Calling method {0} with parameters {1}... ",
invocation.Method.Name,
string.Join(", ", invocation.Arguments.Select(a => (a ?? "").ToString()).ToArray()));
invocation.Proceed();
_output.WriteLine("Done: result was {0}.", invocation.ReturnValue);
}
}Interceptors must be registered with the container: builder.Register(c => new CallLogger(Console.Out))
.Named<IInterceptor>("log-calls");Interceptors can be registered as a particular typed service or with a name as required. Attaching to ComponentsTo attach a service to an interceptor, either attribute its implementation type with the InterceptAttribute: [Intercept("log-calls")]
public class MyCallsAreLogged
{
public virtual int Method();
}Or use the InterceptedBy() extension: builder.Register<MyCallsAreLogged>().InterceptedBy("log-calls");Usage with ExpressionsComponents created using expressions, or those registered as instances, cannot be subclassed by the DynamicProxy2 engine. In these cases, it is necessary to use interface-based proxies. Component RegistrationsTo enable proxying via interfaces, the component must provide its services through interfaces only. For best performance, all such service interfaces should be part of the registration, i.e. included in As<X>() clauses. | |