inversionhourglass / Rougamo

Compile-time AOP component. Works with any method, whether it is async or sync, instance or static. Uses an aspectj-like pattern to match methods.
MIT License
393 stars 47 forks source link

在现有特征匹配的基础上增加对被标记了的Attribute的方法筛选 #48

Closed yuwenhuisama closed 10 months ago

yuwenhuisama commented 12 months ago

现有的Attribute代理织入方法需要显式地在程序集级别指定代理,但是如果是编写library用于给其他人使用的、实现了IMo的基础类,就还需要其他人也在他的程序集中声明,显得不是很方便。

example:

// -----------------------------------------------------------------------
// <copyright file="PlaintTypeRpcPropertySetterMo.cs" company="Little Princess Studio">
// Copyright (c) Little Princess Studio. All rights reserved.
// </copyright>
// -----------------------------------------------------------------------

namespace LPS.Common.Rpc.RpcProperty.Weaving;

using LPS.Common.Debug;
using LPS.Common.Entity;
using Rougamo;
using Rougamo.Context;

/// <summary>
/// Represents a method object that implements the <see cref="IMo"/> interface and provides
/// interception for plain type RPC property getters.
/// </summary>
public class PlaintTypeRpcPropertySetterMo : IMo
{
    /// <inheritdoc/>
    public AccessFlags Flags => AccessFlags.Instance | AccessFlags.PropertySetter;

    /// <inheritdoc/>
    public string? Pattern => "setter(int||string||float||bool||LPS.Common.Rpc.MailBox *)";

    /// <inheritdoc/>
    public Feature Features => Feature.EntryReplace;

    /// <inheritdoc/>
    public double Order => 1.0;

    /// <inheritdoc/>
    public void OnEntry(MethodContext context)
    {
        var caller = (context.Target as BaseEntity)!;

        // here
        var propName = context.Method.Name[4..];
        var isRpcProperty = context.Target
            .GetType()
            .GetProperty(propName)?
            .IsDefined(typeof(RpcWrappedPropertyAttribute), false) ?? false;

        if (isRpcProperty && caller.IsPropertyTreeBuilt)
        {
            var rpcProp = caller.GetRpcPropertyByName(propName);

            var newValue = context.Arguments[0];
            ((IValueSetable)rpcProp).SetValue(newValue);

            context.ReplaceReturnValue(this, context.Arguments[0]);
        }
    }

    /// <inheritdoc/>
    public void OnException(MethodContext context)
    {
    }

    /// <inheritdoc/>
    public void OnExit(MethodContext context)
    {
    }

    /// <inheritdoc/>
    public void OnSuccess(MethodContext context)
    {
    }
}

现在只能在OnEntry里面再动态地读对应的Attribute来判断是否进行拦截,希望能增加一个能基于指定的Attributes对方法进行筛选匹配机制。

inversionhourglass commented 12 months ago

好的,这个加入后续开发计划中

inversionhourglass commented 10 months ago

Attribute匹配的功能已在2.1.1版本中添加,使用方式如下:

对应你上面的代码,Pattern部分可以改成:

public string? Pattern => "setter(int||string||float||bool||LPS.Common.Rpc.MailBox *) && attr(exec RpcWrappedPropertyAttribute)";