Java has AOP with aspectJ and weaving (LTW load time with a proxy, and complile time CTW)
C# (Castle) has intersceptors, that use a (dynamic) proxy as well. You can see it as the LTW variant.
I used this setup in c#.
It is no big magic, and quite limited code.
Autofac 5.1.0
Autofac.Extras.DynamicProxy 5.0.0
Castle.Core 4.4.0
The trick is to
- define some attibute, that you use as intersceptor attribute
- define a intersceptor, that checks for the attribute on the method called
- define a interface with a method and the attribute on the interface method
- define implementation class of the interface
- register the whole setup with autofac
- test/run/go
1) define some attibute
using System;
[AttributeUsage(
AttributeTargets.Method,
AllowMultiple = true)]
public class SomeAttribute : Attribute
{
public long Id { get; set; }
}
2) Define a Castle dynamic intersceptor (aka proxy)
using Castle.DynamicProxy;
using System;
public class SomeInterceptor : IInterceptor
{
public void Intercept(IInvocation invocation)
{
if (Attribute.IsDefined(invocation.Method, typeof(SomeAttribute)))
{
Console.Write("Method called: " + invocation.Method.Name);
}
invocation.Proceed();
}
}
Now, create a object with a interface (dont forget, put the attribute on the interface, not on the impl!)
3) define a interface
public interface AOPTest
{
[Some(Id = 10)]
void DoSomething();
}
4) define implementation :
public class AOPTestImpl : AOPTest
{
public void DoSomething()
{
}
}
5) register the whole setup with autofac
builder.RegisterType<AOPTestImpl>()
.As<AOPTest>()
.EnableInterfaceInterceptors()
.InterceptedBy(typeof(SomeInterceptor));
builder.RegisterType<SomeInterceptor>().AsSelf();
6) test/run/go : run the whole setup:
using Autofac;
using Autofac.Extras.DynamicProxy;
using (var scope = bootstrap.BootStrap.Container.BeginLifetimeScope())
{
var aOPTest = scope.Resolve<AOPTest>();
aOPTest.DoSomething();
}
I dont know how it excactly works but the idea is:
interface -> proxy -> implementation
So if you call the implementation over the interface, the proxy/intersceptor is in between.
Note: If you call other code inside the doSomething() method that needs intersception as well, you probably need a autofac class intersceptor EnableClassInterceptors
Note: it is not the fastest solution in the world. Probably some filtering intersceptor is faster, and compile time weaving like Fody or PostSharp are probably faster. But this will do a lot of times.
Note: if you need something done @Before start of the method, code it before the invocation.Proceed(); If you need something done at the end, code it if @After the invocation.Proceed() call:
@Before
DoSomething(){...}
@After