[英]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.