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

FluentAspects -- 基于 Fluent API 的 Aop

程序员文章站 2022-05-18 17:47:10
FluentAspects 基于 Fluent API 的 Aop Intro 上次我们做了一个简单的 AOP 实现示例,但是实现起来主要是基于 来做的,对于代码的侵入性太强,于是尝试实现基于 Fluent API 的方式来做 AOP 。 抽象 InterceptorResolver 原来获取方法执 ......

fluentaspects -- 基于 fluent api 的 aop

intro

上次我们做了一个简单的 aop 实现示例,但是实现起来主要是基于 attribute 来做的,对于代码的侵入性太强,于是尝试实现基于 fluent api 的方式来做 aop 。

抽象 interceptorresolver

原来获取方法执行的 interceptor 是通过 attribute 来获取的,现在我们只需要将获取 interceptor 的逻辑抽象出来就可以实现不必依赖于 attribute

方法执行上下文定义:

public interface iinvocation
{
    public methodinfo proxymethod { get; }

    public object proxytarget { get; }

    public methodinfo method { get; }

    public object target { get; }

    public object[] arguments { get; }

    type[] genericarguments { get; }

    public object returnvalue { get; set; }
}

方法拦截器 interceptor 接口定义:

public interface iinterceptor
{
    task invoke(iinvocation invocation, func<task> next);
}

自定义 interceptor 只需要继承这个接口实现相应的逻辑就好了

获取 iinterceptorresolver 接口定义:

public interface iinterceptorresolver
{
    ireadonlycollection<iinterceptor> resolveinterceptors(iinvocation invocation);
}

原来基于 attribute 获取 interceptor 的方式可以实现一个 attributeinterceptorresolver

想要基于 fluent api 来获取 interceptor ,只需要实现基于 fluent api 的 interceptorresolver 就可以了,具体的实现可以参考 fluentconfiginterceptorresolver

示例预览

测试服务定义:

public interface isvc1
{
    void invoke();
}

public interface isvc2
{
    void invoke();
}

public class svc2 : isvc2
{
    public void invoke()
    {
        console.writeline($"invoking in {gettype().name} ...");
    }

    public void invoke2()
    {
        console.writeline($"invoking in {gettype().name} ...");
    }
}

public class svc3
{
    public virtual void invoke()
    {
        console.writeline($"invoking in {gettype().name} ...");
    }
}

public class svc4
{
    public virtual void invoke()
    {
        console.writeline($"invoking in {gettype().name} ...");
    }

    public void invoke2()
    {
        console.writeline($"invoking2 in {gettype().name} ...");
    }

    public virtual void invoke3()
    {
        console.writeline($"invoking3 in {gettype().name} ...");
    }
}

测试 interceptor

internal class loginterceptor : iinterceptor
{
    public async task invoke(iinvocation invocation, func<task> next)
    {
        console.writeline($"invoke {invocation.proxymethod} in {gettype().name} begin");
        await next();
        console.writeline($"invoke {invocation.proxymethod} in {gettype().name} end");
    }
}

测试代码:

public static void main(string[] args)
{
    var services = new servicecollection();
    services.addfluentaspects(options =>
    {
        // 为所有拦截的方法添加拦截器
        options.interceptall()
            .with<loginterceptor>()
            ;
        // 对 svc3 类型禁用拦截器
        options.nointercepttype<svc3>();
        // svc4 类型的 invoke3() 方法禁用拦截器
        options.nointerceptmethod<svc4>(s => s.invoke3());
    });
    services.addtransientproxy<svc4>();
    var serviceprovider = services.buildserviceprovider();
    var proxyfactory = serviceprovider.getrequiredservice<iproxyfactory>();

    var svc1 = proxyfactory.createproxy<isvc1>();
    svc1.invoke();
    console.writeline();

    var svc2 = proxyfactory.createproxy<isvc2, svc2>();
    svc2.invoke();
    console.writeline();

    var svc3 = proxyfactory.createproxy<svc3>();
    svc3.invoke();
    console.writeline();

    var svc4 = proxyfactory.createproxywithtarget<isvc2, svc2>(new svc2());
    svc4.invoke();
    console.writeline();

    // 直接从注册的服务中获取
    var svc5 = serviceprovider.getrequiredservice<svc4>();
    svc5.invoke();
    console.writeline();
    svc5.invoke2();
    console.writeline();
    svc5.invoke3();
    console.writeline();

    console.writeline("finished");
    console.readline();
}

输出结果预览:

FluentAspects -- 基于 Fluent API 的 Aop

more

最近十几天的时间一直在搞这个,相比之前写的示例,真正实现一个完整的 aop 框架还是要做比较多的事情的,之前的 aop 示例,没有考虑泛型,也没有什么设计,所以前面的示例只能算是一个小玩具。

在实现的过程中,参考了很多 aspectcore 的代码,有一些代码甚至是直接从 aspectcore 里抄过来的。

推荐大家有机会研究学习一下柠檬大佬的 aspectcore 的源码,这个 aop 框架的代码组织,代码细节都挺不错的。

aspectcore 源码地址: https://github.com/dotnetcore/aspectcore-framework

reference