using this tutorial i came across an issue i can't figure out. : [https://aspnetboilerplate.com/Pages/Documents/Articles/Aspect-Oriented-Programming-using-Interceptors/index.html])
When i call my api, my intercept constructor is hit but never the method void Intercept(IInvocation invocation). When i use unit testing, my interceptor is called perfectly. What am i doing wrong?
I've debugged extensivly and on app startup the registar class is called for every application method.
my code
public static class MeasureDurationInterceptorRegistrar
{
public static void Initialize(IKernel kernel)
{
kernel.ComponentRegistered += Kernel_ComponentRegistered;
}
private static void Kernel_ComponentRegistered(string key, IHandler handler)
{
if (typeof(IApplicationService).IsAssignableFrom(handler.ComponentModel.Implementation))
{
handler.ComponentModel.Interceptors.Add
(new InterceptorReference(typeof(MeasureDurationInterceptor)));
}
}
}
public class MeasureDurationInterceptor : IInterceptor
{
public ILogger Logger { get; set; }
public MeasureDurationInterceptor()
{
Logger = NullLogger.Instance;
}
public void Intercept(IInvocation invocation)
{
//Before method execution
var stopwatch = Stopwatch.StartNew();
//Executing the actual method
invocation.Proceed();
//After method execution
stopwatch.Stop();
Logger.InfoFormat(
"MeasureDurationInterceptor: {0} executed in {1} milliseconds.",
invocation.MethodInvocationTarget.Name,
stopwatch.Elapsed.TotalMilliseconds.ToString("0.000")
);
}
}
public class MyGlobyApplicationModule : AbpModule
{
public override void PreInitialize()
{
//Adding authorization providers
Configuration.Authorization.Providers.Add<AppAuthorizationProvider>();
//Adding custom AutoMapper configuration
Configuration.Modules.AbpAutoMapper().Configurators.Add(CustomDtoMapper.CreateMappings);
////register custom interceptor for tenant control
//TenantAuthorizationInterceptorRegistrar.Initialize(IocManager.IocContainer.Kernel);
MeasureDurationInterceptorRegistrar.Initialize(IocManager.IocContainer.Kernel);
}
5 Answer(s)
-
0
Is your method public virtual? Related issue: aspnetboilerplate/aspnetboilerplate#3237
-
0
It's not, but how come abpauthorize works then? I cannot change all my methods to virtual. this seems bad practice.
the real goal is to create a custom attribute and places on various services. it's for methods that are not authorized but we must have a tenant id.
-
0
how come abpauthorize works then?
In ASP.NET Core, ABP creates Application Services as Controllers and uses the native Authorization Filter. Since we do not rely on AuthorizationInterceptor, AbpAuthorize works even if the method is not virtual.
In MVC5, ABP builds Dynamic Web API Controllers for the interfaces, which satisfies the first condition in AbpAuthorize attribute notes:
- You can use it for any public method if the method is called over an interface (like Application Services used over interface).
- A method should be virtual if it's called directly from a class reference (like ASP.NET MVC or Web API Controllers).
- A method should be virtual if it's protected. So although the article that you came across was written for MVC5, the examples are still valid.
I cannot change all my methods to virtual. this seems bad practice.
Decide if you want to use interceptors, and then write the correct code for it.
-
0
Hi Aaron,
Thank you for the response. Because you have mentioned filters, i've been digging around them. Turns out that is a better choice for me than interceptors. Went through the source code off abp and managed to replicate the [abpauthorize] behaviour.
The more i learn about abp, the more i am impressed by it!
Thank you for your help.
-
0
That's great :)