如何使用已签名自定义属性的DispatchProxy拦截方法?

问题描述 投票:0回答:1

我想使用我的 DispathProxy 拦截方法。所以我创建了一个自定义代理类,如下所示。

    public abstract class InterceptorProxy<T>: DispatchProxy
    {
        private T? _decorated;
        
        protected override object? Invoke(MethodInfo? targetMethod, object?[]? args)
        {
            try
            {
                OnBefore(targetMethod,args);
                
                var result = targetMethod?.Invoke(_decorated, args);
                
                OnAfter(targetMethod, args, result);
                
                return result;
            }
            catch (TargetInvocationException e)
            {
                OnException(targetMethod, args, e);
                throw;
            }
        }
        
        public static T? Create(T decorated)
        {
            object? proxy = Create<T, InterceptorProxy<T>>();
            ((InterceptorProxy<T>)proxy!)?.SetParameters(decorated);

            return (T)proxy!;
        }
        
        private void SetParameters(T decorated)
        {
            _decorated = decorated ?? throw new ArgumentNullException(nameof(decorated));
        }
        
        protected virtual void OnException(MethodInfo? methodInfo, object?[]? args, Exception exception) { }
        protected virtual void OnAfter(MethodInfo? methodInfo, object?[]? args, object? result) { }
        protected virtual void OnBefore(MethodInfo? methodInfo, object?[]? args) { }
    }

我有一个自定义属性来签署我的方法。

public class DispachedAttribute : Attribute
{
    public string Type { get; set; }
    public DispatchedAttribute(string type)
    {
        Type = type;
    }
}

我想拦截只用这个属性签名的方法。

在控制器中:

[Dispached("POST")]
public ResponseDTO Run(RequestDTO requestDTO)
{
    var result = service.Get(requestDTO);
    return result;
}

任何班级:

public class myclass{
  [Dispached("Do")]
  public string Run(string param)
  {
    // do something
    return param;
  }
}

当这个方法运行时,我的拦截器应该自动工作。我该怎么做?

c# .net asp.net-core
1个回答
0
投票

由于

DispatchProxy.Create
方法需要创建TProxy的实例,如果TProxy是抽象的,则无法创建实例。出现以下错误: enter image description here 如果你想使用 DispatchProxy.Create() 方法,你可能需要确保 TProxy 是一个非抽象类,下面是一个可以作为参考的示例: 可以使用
GetCustomAttributes(typeof(DispachedAttribute), false)
获取与指定类型(DispachedAttribute)关联的自定义属性(Attributes),并通过抛出异常的方式实现方法拦截。

   public class InterceptorProxy<T> : DispatchProxy
{
    private T? _decorated;

    protected override object? Invoke(MethodInfo? targetMethod, object?[]? args)
    {
        try
        {
            var attributes = targetMethod?.GetCustomAttributes(typeof(DispachedAttribute), false);
            if (attributes != null && attributes.Length > 0)
            {

                throw new InvalidOperationException("This method marked with DisallowInterceptAttribute");

            }

            var result = targetMethod?.Invoke(_decorated, args);

            return result;
        }
        catch (TargetInvocationException e)
        {
            OnException(targetMethod, args, e);
            throw;
        }
    }

    public static T? Create(T decorated)
    {
        object? proxy = Create<T, InterceptorProxy<T>>();
        ((InterceptorProxy<T>)proxy!)?.SetParameters(decorated);

        return (T)proxy!;
    }

    private void SetParameters(T decorated)
    {
        _decorated = decorated ?? throw new ArgumentNullException(nameof(decorated));
    }

    protected virtual void OnException(MethodInfo? methodInfo, object?[]? args, Exception exception) { }
        
}

我的服务:

public interface IMyService
{
    [Dispached("POST")]
    void DoSomething();
}
public class MyService : IMyService
{
       
    public void DoSomething()
    {
        Console.WriteLine("Doing something...");
    }
}

控制器:

public class HomeController : Controller
{
    private readonly IMyService _myService;

    public HomeController()
    {
        _myService = InterceptorProxy<IMyService>.Create(new MyService());
    }

    [HttpPost]
       
    public IActionResult Index()
    {
        _myService.DoSomething();
        return Ok("OKK");
    }
}

当我使用具有自定义属性的方法时,将抛出我的自定义异常信息: enter image description here

© www.soinside.com 2019 - 2024. All rights reserved.