3

I am trying to have a cross cutting concern intercept my calls on my controller but for some reason they aren't being intercepted.

I am basically trying to get the example here to work: http://simpleinjector.readthedocs.org/en/latest/InterceptionExtensions.html

They have some other info in the interception section here too: http://simpleinjector.readthedocs.org/en/latest/advanced.html

I have a feeling it is because I am not setting up the Container correctly. Could someone show me how I need to change my main to see "Intercepted!!!" after the calls on the Controller are made? Also, can someone tell me if the setup for the Container was wrong, and if so, explain my error(s).

The Code:

static void Main()
{
    Console.WriteLine("Start");    

    RedisController2 redisController = new RedisController2();    

    Container _container = new Container();
    _container.InterceptWith<MonitoringInterceptor>(type => type == typeof(IRedisController2));
    _container.RegisterSingle<MonitoringInterceptor>();    

    redisController.PrintSomething();
    redisController.PrintOther();    

    Console.WriteLine("Press any key to exit.");
    Console.ReadKey();
}

internal class MonitoringInterceptor : IInterceptor
{    

    public MonitoringInterceptor()
    {    

    }    

    public void Intercept(IInvocation invocation)
    {
        invocation.Proceed();    

        //var decoratedType = invocation.InvocationTarget.GetType();    

        Console.Write("Intercepted!!!");
        Console.ReadKey();
    }
}
Tony
  • 133
  • 2
  • 11

2 Answers2

5

The problem is due to the fact that the Container is not creating the Controller and therefore cannot intercept calls made to it. Try this:

Console.WriteLine("Start");    

Container _container = new Container();
_container.Register<IRedisController2, RedisController2>(); // 1
_container.InterceptWith<MonitoringInterceptor>(type => 
    type == typeof(IRedisController2));
_container.RegisterSingle<MonitoringInterceptor>();    

IRedisController2 redisController =
    _container.GetInstance<IRedisController2>(); // 2, 3

redisController.PrintSomething();
redisController.PrintOther();    

Console.WriteLine("Press any key to exit.");
Console.ReadKey();

Notice that I have:

  1. added code to register the Controller
  2. added code to request an instance of the Controller from the Container
  3. changed the type being created from RedisController2 to IRedisController2 (because IRedisController2 is what has been configured for interception)
qujck
  • 14,388
  • 4
  • 45
  • 74
1

Assuming that SimpleInjector is working in the same way as 90% of all IOC containers, it uses RealProxy under the covers* (given the signature it is most likely, although completely against the spirit of SimpleInjector).

Note: The Interception extensions code snippets use .NET’s System.Runtime.Remoting.Proxies.RealProxy class to generate interception proxies. The RealProxy only allows to proxy interfaces. [source]

RealProxy works with interfaces, due to obvious reason (if you think deeply about it for a while). Even if it could work with a base class, that base class must declare its method as virtual for your code to have worked.

Rework your code to use interfaces when calling RedisController2, and remove all references to RedisController2 except at registration.

Steven
  • 166,672
  • 24
  • 332
  • 435
Aron
  • 15,464
  • 3
  • 31
  • 64