Interpose.Core Changes

I’m writing this from the 2018 MVP Global Summit!

Got my first pull request for Interpose.Core: it came from @x2764tech and it was suggested that Interpose should target .NET Standard. For some reason, I had come to the impression that it wasn’t possible – I *had* tried – but now it seems otherwise. Also, I got a heads up that the unit tests were failing for attribute-based interception, and I now fixed it.

Interpose.Core is now at version 1.4.0. Some of the changes were:

  • BUG: fixed interception with attributes where the interception attribute was being applied at the method level, not class
  • IMPROVEMENT: targeting .NET Standard instead of .NET Core
  • IMPROVEMENT: added caching of handler instances
  • IMPROVEMENT: added support for providing a service provider
  • IMPROVEMENT: small fixes here and there

Huge thanks to x2764tech for the contribution! Winking smile

Interpose.Core Updates

Some of you may have read my previous post on Interpose.Core. I’ve made a few modifications since:

  • Added caching for type generators, meaning, you won’t have to generate the same types twice
  • Added DispatchProxy interception; if you don’t know DispatchProxy, it’s .NET Core’s replacement for RealProxy, the transparent proxy mechanism that exists in .NET “full” framework. It may be used as an alternative to interface interception, as we don’t need to generate a type at runtime

The source code is updated and so is the NuGet package. Do have a look and share your thoughts! Winking smile

Introducing Interpose.Core

Update: see this post and this one.

I’m writing this from the 2018 MVP Global Summit!

Some of you may remember a series of posts I wrote about AOP and code interception in .NET. In them I built an AOP framework from scratch that could do custom interception. A few years passed by and I decided to revisit it and turn it into a .NET Core project: I introduce to you Interpose.Core.

Interpose: place or insert between one thing and another.

Interpose is available as an open source project (under Lesser GNU Public License) which you can get from GitHub or NuGet. It can do type and instance interception:

  • Type: virtual methods, the type to intercept cannot be sealed
  • Instance: interface and dynamic interception

Interpose uses Roslyn to generate the proxy types. As it targets .NET Core, you can use it on any supported platform.

At its core, you have an interceptor class (IInstanceInterceptor or ITypeInterceptor) and you ask for an instance or a type to be intercepted using a given handler (instance or type). It then generates a proxy instance (or type, which you must instantiate yourself). When using the generated proxy instance, for the target methods or properties, it will execute the provided handler.

So, what’s an handler like? An handler is just any implementation of the IInterceptionHandler method, that offers a single method, Invoke. This method takes a parameter that describes all of the execution context (target object, target method, parameters). From it, you can run the base implementation before or after performing any actions, or you can skip it altogether, in which case, you must provide a return value yourself.

Two instance interception examples, one for each interceptor, first, interface:

var interceptor = new InterfaceInterceptor();
var instance = new MyType();
var handler = new MyHandler();
var proxy = interceptor.Intercept(instance, typeof(IMyType), handler) as IMyType;

As you can see, you need to explicitly state which interface in the target instance you wish to intercept.

For dynamic, you can do something similar:

var interceptor = new DynamicInterceptor(); var instance = new MyType(); var handler = new MyHandler(); dynamic proxy = interceptor.Intercept(instance, null, handler);

Here you don’t need to specify an interface, but you do need to declare your proxy instance as dynamic.

Types are easy to intercept too, the major difference is that you pass types, not instances:

var interceptor = new VirtualMethodInterceptor();

var proxyType = interceptor.Intercept(typeof(MyType), typeof(MyHandler));

var proxy = Activator.CreateInstance(proxyType) as MyType;

Here the handler must be a public non-abstract class with a public parameterless constructor.

A very simple handler could be:

class MyHandler : IInterceptionHandler

{

public void Invoke(InterceptionArgs args)

{

if (args.Method.ReturnType == typeof(int))

{

//always return 100

args.Result = 100;

}

else

{

Console.Out.WriteLine(“Before base method call”);

args.Proceed();

Console.Out.WriteLine(“After base method call”);

}

}

}

There are a couple of extensions that allow you to use a registry for mapping methods to intercept to handlers or handlers defined as attributes.

You can integrate it with .NET Core’s dependency injection framework:

services.AddInterfaceInterceptor();

services.AddVirtualMethodInterceptor();

services.AddDynamicInterceptor();

Still some features missing, such as caching of generated proxy types, interception of generic types or the ability to maintain custom attributes from the base types or interfaces. Will try to address these when I have the time. Also, might be useful to have a small library of common handlers (logging, exception handling, measuring time, etc), if this ever comes to live, I will do it in a different assembly.

In the meantime, enjoy it and let me know what you think!