2

I am trying to intercept calls to a class, and virtual methods are working correctly. However, I would also like to intercept calls to the constructor, but I think this is not possible at least in a straight-forward way, because as stipulated on the Autofac manual:

Use Virtual Methods

Class interception requires the methods being intercepted to be virtual since it uses subclassing as the proxy technique.

Quick example:

Interceptor:

public class TestInterceptor : IInterceptor
{
    public void Intercept(IInvocation invocation)
    {
        if (invocation.Method.Name == ".ctor")
            Console.WriteLine("Intercepted ctor");

        invocation.Proceed();
    }
}

Intercepted class:

public class ClassToBeIntercepted
{
    public ClassToBeIntercepted()
    {
        Console.WriteLine("ClassToBeIntercepted ctor");
    }

    public virtual void DoSomething()
    {
        Console.WriteLine("Doing something");
    }
}

Example test:

[TestClass]
public class TestInterception
{
    public TestContext TestContext { get; set; }

    // Create your builder.
    private static readonly ContainerBuilder builder = new();
    static Hierarchy _hierarchy = (Hierarchy)LogManager.GetRepository();
    private static IContainer container;
    protected static ILifetimeScope scope;

    [TestMethod]
    public void TestConstructorInterception()
    {
        builder.RegisterType<TestInterceptor>();
        builder.RegisterType<ClassToBeIntercepted>()
         .AsSelf()
         .EnableClassInterceptors()
         .InterceptedBy(typeof(TestInterceptor));

        using (var scope1 = builder.Build().BeginLifetimeScope())
        {
            scope1.Resolve<ClassToBeIntercepted>().DoSomething();
        }
    }
}

Is there a work around to achieving this?

elgato
  • 506
  • 1
  • 5
  • 20
  • Why do you want this? What's the goal here? Are you executing any logic in your constructor *(hint: you probably shouldn't)*. Maybe show some of your code to better explain the situation and the goal. – Julian May 31 '23 at 18:48
  • The goal is only to log which constructor has been used when activating a class and possibly the values of the parameters. I will add a quick example – elgato May 31 '23 at 19:19
  • 1
    Autofac is using Castle DynamicProxy for interception - the question will be whether Castle can intercept it, not Autofac. – Travis Illig Jun 01 '23 at 12:36
  • According to https://stackoverflow.com/a/5852079/5364231: "No it is not possible. For the simple reason that the creation of proxies is managed by ProxyGenerator which precludes using new with proxies." Is that correct? – elgato Jun 01 '23 at 15:03
  • If I am not mistaken, the moment DynamicProxy news up a class is in the ProxyGenerator (https://github.com/castleproject/Core/blob/dca4ed09df545dd7512c82778127219795668d30/src/Castle.Core/DynamicProxy/ProxyGenerator.cs#L1472) which only uses Activator.CreateInstance, so it seems the answer again is No – elgato Jun 01 '23 at 15:13
  • 1
    If you only want to add logging you should look at the OnActivated autofac Event – Cyril Durand Jun 09 '23 at 08:11

0 Answers0