Reputation: 287
I'm using Autofac.Extras.DynamicProxy2 to perform some method interception on a service implementation.
The service has quite a few methods and I only want to target a few.
Is there a better practice besides than checking for invocation target name against an approved string dictionary of methods I want to intercept?
public void Intercept(IInvocation invocation)
{
invocation.Proceed();
if (ContinueIntercept(invocation))
{
// Do intercept work
}
}
private bool ContinueIntercept(IInvocation invocation)
{
// Logic to compare invocation.MethodInvocationTarget.Name
}
It really doesn't add all that much over head, but it still feels like a poor way to do it. Especially since adding this to a specific service implementation means it will intercept all of the method calls of the base class common implementation. It wouldn't be as bad if it only intercepted the derived class.
I see that Castle.DynamicProxy2 has ways to specify invocation target, but I don't see how to wire that up with autofac.
Upvotes: 3
Views: 3565
Reputation: 16192
You can use a IProxyGenerationHook
to specify on which method the ProxyBuilder
should generate a proxy.
public class FooProxyGenerationHook : IProxyGenerationHook
{
public void MethodsInspected()
{ }
public void NonProxyableMemberNotification(Type type, MemberInfo memberInfo)
{ }
public Boolean ShouldInterceptMethod(Type type, MethodInfo methodInfo)
{
if (type == typeof(Foo) && methodInfo.Name == "Do")
{
return true;
}
return false;
}
}
Then, you can register it this way :
ProxyGenerator generator = new ProxyGenerator();
FooProxyGenerationHook hook = new FooProxyGenerationHook();
IFoo foo = generator.CreateClassProxyWithTarget<Foo>(new Foo(), new ProxyGenerationOptions(hook), new FooInterceptor());
In order to avoid calling the IProxyGenerationHook
for each proxy, you should have only one instance of hook
.
With DynamicProxy2, you can use this code :
FooProxyGenerationHook hook = new FooProxyGenerationHook();
ContainerBuilder builder = new ContainerBuilder();
builder.RegisterType<FooInterceptor>().AsSelf();
builder.RegisterType<Foo>().As<IFoo>()
.EnableClassInterceptors(new ProxyGenerationOptions(hook))
.InterceptedBy(typeof(FooInterceptor));
Upvotes: 4