繁体   English   中英

用属性C#包装方法

[英]Wrapping a method with Attributes C#

我正在使用Polly .NET用重试行为包装我的方法。 Polly使它变得非常轻松和优雅,但我正在尝试将其提升到一个新的水平。

请参见以下Python示例(可能有一些错误,但这不是重点):

@retry(wait_exponential_multiplier=250,
           wait_exponential_max=4500,
           stop_max_attempt_number=8,
           retry_on_result=lambda failures_count: failures_count > 0)
def put():
    global non_delivered_tweets

    logger.info("Executing Firehose put_batch command on {} tweets".format(len(non_delivered_tweets)))
    response = firehose.put_record_batch(DeliveryStreamName=firehose_stream_name, Records=non_delivered_tweets)

    failures_count = response["FailedPutCount"]
    failures_list = []
    if failures_count > 0:
        for index, request_response in enumerate(response["RequestResponses"]):
            if "ErrorCode" in request_response:
                failures_list.append(non_delivered_tweets[index])

    non_delivered_tweets = failures_list
    return failures_count

编写上述代码的好处:

  • 您阅读了核心逻辑
  • 您认为在指定情况下重试了核心逻辑

由于两者没有混合-在我看来,这使代码更具可读性。

我想在C#上使用属性使用Polly实现此语法。 我对C#属性了解最少,而对于我所读的内容,这似乎是不可能的。

我很高兴有这样的事情:

class Program
{
    static void Main(string[] args)
    {
        var someClassInstance = new SomeClass();
        someClassInstance.DoSomething();
    }
}

class Retry : Attribute
{
    private static readonly Policy DefaultRetryPolicy = Policy
        .Handle<Exception>()
        .WaitAndRetry(3, retryAttempt => TimeSpan.FromSeconds(5));

    public void Wrapper(Action action)
    {
        DefaultRetryPolicy.Execute(action);
    }
}

class SomeClass
{
    [Retry]
    public void DoSomething()
    {
        // core logic
    }
}

如您所见,在我的示例中- [Retry]属性用重试逻辑包装DoSomething方法。 如果可能的话,我将很高兴学习如何实现它。

非常感谢您的帮助!

当然可以。 但是,它比Python更复杂。 与Python装饰器是可以交换装饰对象的可执行代码的Python不同,C#中的属性是纯元数据。 .NET属性无权访问正在装饰的对象,而是代表自己。

因此,您必须自己连接属性和方法,尤其是自己替换方法(即,用核心逻辑替换功能,同时也包含重试等功能)。 后者不可能在C#中隐式地实现,您必须显式地做到这一点。

它的工作原理应与此类似:

class RetryExecutor
{
    public static void Call(Action action)
    {
        var attribute = action.Method.GetCustomAttribute(typeof(Retry));
        if (attribute != null)
        {
             ((Retry)attribute).Wrap(action);
        }
        else
        {
            action();
        }
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM