一個簡單、基於AbpInterceptor的攔截器示例: 攔截器調用順序,可參考打上斷點調試分析: AutofacRegistration.Populate(內部調用Autofac.Extras.DynamicProxy) SimpleAsyncInterceptor.Intercept Castl ...
一個簡單、基於AbpInterceptor的攔截器示例:
using Microsoft.Extensions.DependencyInjection;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Volo.Abp;
using Volo.Abp.DynamicProxy;
namespace ConsoleApp1
{
public interface ICanLogOnObject
{
List<string> Logs { get; }
}
public class SimpleAsyncInterceptor : AbpInterceptor
{
public override void Intercept(IAbpMethodInvocation invocation)
{
(invocation.TargetObject as ICanLogOnObject)?.Logs?.Add($"{GetType().Name}_Intercept_BeforeInvocation");
invocation.ProceedAsync();
(invocation.TargetObject as ICanLogOnObject)?.Logs?.Add($"{GetType().Name}_Intercept_AfterInvocation");
}
public override async Task InterceptAsync(IAbpMethodInvocation invocation)
{
await Task.Delay(5);
(invocation.TargetObject as ICanLogOnObject)?.Logs?.Add($"{GetType().Name}_InterceptAsync_BeforeInvocation");
await invocation.ProceedAsync();
(invocation.TargetObject as ICanLogOnObject)?.Logs?.Add($"{GetType().Name}_InterceptAsync_AfterInvocation");
await Task.Delay(5);
}
}
public class SimpleInterceptionTargetClass : ICanLogOnObject
{
public List<string> Logs { get; } = new List<string>();
public virtual void DoIt()
{
Logs.Add("ExecutingDoIt");
}
public virtual int GetValue()
{
Logs.Add("ExecutingGetValue");
return 42;
}
public virtual async Task<int> GetValueAsync()
{
Logs.Add("EnterGetValueAsync");
await Task.Delay(5);
Logs.Add("MiddleGetValueAsync");
await Task.Delay(5);
Logs.Add("ExitGetValueAsync");
return 42;
}
public virtual async Task DoItAsync()
{
Logs.Add("EnterDoItAsync");
await Task.Delay(5);
Logs.Add("MiddleDoItAsync");
await Task.Delay(5);
Logs.Add("ExitDoItAsync");
}
}
class Program
{
static void Main(string[] args)
{
// 服務容器
var services = new ServiceCollection();
services.AddTransient<SimpleAsyncInterceptor>();
services.AddTransient<SimpleInterceptionTargetClass>();
services.OnRegistred(register =>
{
// 添加攔截器
if (typeof(SimpleInterceptionTargetClass) == register.ImplementationType)
{
register.Interceptors.Add<SimpleAsyncInterceptor>();
}
});
var application = services.AddApplication<AbpTestModule>(options =>
{
options.UseAutofac();
});
var rootServiceProvider = services.BuildServiceProviderFromFactory();
var testServiceProvider = rootServiceProvider.CreateScope();
var ServiceProvider = testServiceProvider.ServiceProvider;
application.Initialize(ServiceProvider);
// 攔截器 代碼 ↓
var target = ServiceProvider.GetRequiredService<SimpleInterceptionTargetClass>();
target.DoIt();
foreach (var log in target.Logs)
{
Console.WriteLine(log);
}
Console.WriteLine("Done");
Console.Read();
}
}
}
攔截器調用順序,可參考打上斷點調試分析:
AutofacRegistration.Populate(內部調用Autofac.Extras.DynamicProxy) --> SimpleAsyncInterceptor.Intercept --> CastleAbpMethodInvocationAdapter.Proceed(內部調用Castle.DynamicProxy)