Reputation: 25019
To intercept a particular method with Ninject, I do this:
[MyInterceptor] void MyMethod()
or this:
Kernel.InterceptAround<IMyClass>(c => c.MyMethod(), inv => { ... }, inv => { ... });
I want to add all interceptors in a single place like (kernel config) and keep MyMethod
free from any attributes. However, this Kernel.InterceptAround
signature accepting Action
instead IInterceptor
looks weird! I would prefer full control of method execution.
Is it possible to add an interceptor for a particular method (not for a type at all!) without attributes, probably with Ninject extension? I mean a syntax like this:
Kernel.Intercept<IMyClass>(c => c.MyMethod()).With<MyInterceptor>();
Filter by method's name inside the interceptor is not a good option. Feel free to suggest another DI container.
Upvotes: 2
Views: 1942
Reputation: 27861
I would prefer full control of method execution
While InterceptAround
allows you only to specify what happens before and after execution, InterceptReplace
can give you full control by allowing you to invoke IInvocation.Proceed
manually (or not invoke it if you want).
Here is an example:
Create an interceptor like this:
public class Interceptor : IInterceptor
{
public void Intercept(IInvocation invocation)
{
//Do before
invocation.Proceed();
//Do after
}
}
And then you can use the InterceptReplace
method like this:
var my_interceptor = new Interceptor();
Kernel.InterceptReplace<IMyClass>(
c => c.MyMethod(),
inv => my_interceptor.Intercept(inv));
You can create extension methods to help you get a different syntax that you like. Here is an example:
public static class MyExtentionMethods
{
public static void UseInterceptorFor<T>(
this IKernel kernel,
Expression<Action<T>> methodExpr,
IInterceptor interceptor)
{
kernel.InterceptReplace<T>(methodExpr, inv => interceptor.Intercept(inv));
}
}
This allows you to simplify the syntax to be like this:
var my_interceptor = new Interceptor();
Kernel.UseInterceptorFor<IMyClass>(
c => c.MyMethod(),
my_interceptor);
And here is another example for an extension method (based on Alexei Levenkov comment):
public static class MyExtentionMethods
{
public static void UseInterceptorFor<TObject,TInterceptor>(
this IKernel kernel,
Expression<Action<TObject>> methodExpr)
where TInterceptor : IInterceptor
{
var interceptor = kernel.Get<TInterceptor>();
kernel.InterceptReplace<TObject>(methodExpr, inv => interceptor.Intercept(inv));
}
}
Which allows you to do:
Kernel.UseInterceptorFor<IMyClass,Interceptor>(c => c.MyMethod());
Upvotes: 3