欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

6.1 自定义abp拦截器示例

程序员文章站 2022-06-29 14:06:18
一个简单、基于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)