6.1 自定义abp拦截器示例

2023-10-19 19:35:02 浏览数 (2)

一个简单、基于AbpInterceptor的拦截器示例:

代码语言:javascript复制
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)

0 人点赞