The Autofac.Extras.DynamicProxy integration package enables method calls on Autofac components to be intercepted by other components. Common use-cases are transaction handling, logging, and declarative security. You can use Autofac.Extras.DynamicProxy2 for Autofac versions up to 4.0.0

Interceptors must be registered with the container. You can register them either as typed services or as named services. If you register them as named services, they must be named IInterceptor registrations.

Which of these you choose depends on how you decide to associate interceptors with the types being intercepted.

When you register a type being intercepted, you have to mark the type at registration time so Autofac knows to wire up that interception. You do this using the EnableInterfaceInterceptors() and EnableClassInterceptors() registration extensions.

Under the covers, EnableInterfaceInterceptors() creates an interface proxy that performs the interception, while EnableClassInterceptors() dynamically subclasses the target component to perform interception of virtual methods.

Both techniques can be used in conjunction with the assembly scanning support, so you can configure batches of components using the same methods.

Special case: WCF proxy and remoting objects
While WCF proxy objects look like interfaces, the EnableInterfaceInterceptors() mechanism won’t work because, behind the scenes, .NET is actually using a System.Runtime.Remoting.TransparentProxy object that behaves like the interface. If you want interception on a WCF proxy, you need to use the InterceptTransparentProxy() method.

To pick which interceptor is associated with your type, you have two choices.

Your first option is to mark the type with an attribute, like this:

// This attribute will look for a TYPED// interceptor registration:[Intercept(typeof(CallLogger))]publicclassFirst{publicvirtualintGetValue(){// Do some calculation and return a value}}// This attribute will look for a NAMED// interceptor registration:[Intercept("log-calls")]publicclassSecond{publicvirtualintGetValue(){// Do some calculation and return a value}}

When you use attributes to associate interceptors, you don’t need to specify the interceptor at registration time. You can just enable interception and the interceptor type will automatically be discovered.

// Using the TYPED attribute:varbuilder=newContainerBuilder();builder.RegisterType<First>().EnableClassInterceptors();builder.Register(c=>newCallLogger(Console.Out));// Using the NAMED attribute:varbuilder=newContainerBuilder();builder.RegisterType<Second>().EnableClassInterceptors();builder.Register(c=>newCallLogger(Console.Out)).Named<IInterceptor>("log-calls");

The second option is to declare the interceptor at Autofac registration time. You can do this using the InterceptedBy() registration extension:

To 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.

If you are using class interceptors via EnableClassInterceptors() then avoid using the constructor selector UsingConstructor() with it. When class interception is enabled, the generated proxy adds some new constructors that also take the set of interceptors you want to use. When you specify UsingConstructor() you’ll bypass this logic and your interceptors won’t be used.

Castle interceptors only expose a synchronous mechanism to intercept methods - there’s no explicit async/await sort of support. However, given async/await is just syntactic sugar around returning Task objects, you can use Task and ContinueWith() sorts of methods in your interceptor. This issue shows an example of that. Alternatively, there are helper libraries that make async work easier.

As of Castle.Core 4.2.0, the Castle.Core NuGet package version updates but the assembly version does not. Further, the assembly version in Castle.Core 4.1.0 matched the package (4.1.0.0) but the 4.2.0 package back-versioned to 4.0.0.0. In full .NET framework projects any confusion around Castle.Core versioning can be solved by adding an assembly binding redirect to force use of Castle.Core 4.0.0.0.

Unfortunately, .NET core doesn’t have assembly binding redirects so if you have a transitive dependency on Castle.Core through a library like Autofac.Extras.DynamicProxy and you also have a direct dependency on Castle.Core, you may see something like:

Two, if you can’t remove your direct reference or removing it doesn’t work… all of the direct dependencies you have will need to update to version 4.2.0 or higher of Castle.Core. You’ll have to file issues with those projects; it’s not something Autofac can fix for you.