如何为多个 WCF 客户端创建 Polly 的策略
How to create Polly's policy for several WCF Clients
我需要集成第 3 方服务。它有 3 个端点,用于 3 个调用。就是这样,每个 API 调用都有自己的端点和自己的 wsdl。因此,不同调用的 POCO 之间没有任何联系(如继承)。但是这些调用的结果非常相似。特别是每个结果都有 'Errors' 属性,其中包含管道分隔字符串中的错误。一些错误在调用之间共享(具有相同的名称)并且必须以类似的方式处理。
我的目标是在出现异常或错误中出现名为 'EXCEPTION' 的错误时重试调用。我正在尝试使用 Polly 来实现这个目标。我现在看到的唯一方法是为每个调用创建单独的策略。有什么方法可以为所有调用创建单一策略吗?
示例代码如下(在实际项目中*结果类和*服务接口在导入wsdl时由VisualStudio自动生成):
public partial class CreateResult
{
public string Errors {get;set;}
}
public interface ICreateService
{
Task<CreateResult> CreateAsync();
}
public partial class UpdateResult
{
public string Errors {get;set;}
}
public interface IUpdateService
{
Task<UpdateResult> UpdateAsync();
}
public partial class DeleteResult
{
public string Errors {get;set;}
}
public interface IDeleteService
{
Task<DeleteResult> DeleteAsync();
}
public class Connector
{
private readonly ICreateService _createService;
private readonly IUpdateService _updateService;
private readonly IDeleteService _deleteService;
private readonly Policy _policy = ???;
public Connector(ICreateService createService, IUpdateService updateService, IDeleteService deleteService)
{
_createService = createService;
_updateService = updateService;
_deleteService = deleteService;
}
public async Task<CreateResult> CreateAsync()
{
// sample policy: var policy = Policy.Handle<Exception>()
// .OrResult<CreateResult>(r => r.Errors.Contains("EXCEPTION"))
// .Retry();
// Now I need to create such a policy for every call. How can I create a single policy or a factory method to enforce DRY principle?
return _policy.ExecuteAsync(() => _createService.CreateAsync());
}
public async Task<UpdateAsync> UpdateAsync()
{
return _policy.ExecuteAsync(() => _updateService.UpdateAsync());
}
public async Task<DeleteResult> DeleteAsync()
{
return _policy.ExecuteAsync(() => _deleteService.DeleteAsync());
}
}
假设每个 return 类型都有一个 属性 包含 Error
对象的集合,您可以通过让每个策略重用检查该集合的方法来消除一些代码重复。
例如:
public static class PolicyExtensions
{
public static bool ContainsExceptionMessage(this IEnumerable<Error> errors)
{
return errors.Any(error => error.Name.Contains("EXCEPTION"));
}
}
您将需要多个策略,但每个策略都可以重复使用此方法:
var policy = Policy.HandleResult<MyResultClass>(
result => result.Errors.ContainsExceptionMessage())
.Or<Exception>()
.Retry();
如果您的每个 类 实现一个接口,表明它包含错误集合,您还可以创建一个通用函数来 return 策略:
public interface IHasErrors
{
List<Error> Errors { get; }
}
Policy<THasErrors> CreateExceptionPolicy<THasErrors>() where THasErrors:IHasErrors
{
return Policy.HandleResult<THasErrors>(
result => result.Errors.ContainsExceptionMessage())
.Or<Exception>()
.Retry();
}
现在您仍在创建多个策略,但它们更容易创建,并且 none 它们的代码是重复的。
var policy = CreateExceptionPolicy<UpdateResult>();
我需要集成第 3 方服务。它有 3 个端点,用于 3 个调用。就是这样,每个 API 调用都有自己的端点和自己的 wsdl。因此,不同调用的 POCO 之间没有任何联系(如继承)。但是这些调用的结果非常相似。特别是每个结果都有 'Errors' 属性,其中包含管道分隔字符串中的错误。一些错误在调用之间共享(具有相同的名称)并且必须以类似的方式处理。
我的目标是在出现异常或错误中出现名为 'EXCEPTION' 的错误时重试调用。我正在尝试使用 Polly 来实现这个目标。我现在看到的唯一方法是为每个调用创建单独的策略。有什么方法可以为所有调用创建单一策略吗?
示例代码如下(在实际项目中*结果类和*服务接口在导入wsdl时由VisualStudio自动生成):
public partial class CreateResult
{
public string Errors {get;set;}
}
public interface ICreateService
{
Task<CreateResult> CreateAsync();
}
public partial class UpdateResult
{
public string Errors {get;set;}
}
public interface IUpdateService
{
Task<UpdateResult> UpdateAsync();
}
public partial class DeleteResult
{
public string Errors {get;set;}
}
public interface IDeleteService
{
Task<DeleteResult> DeleteAsync();
}
public class Connector
{
private readonly ICreateService _createService;
private readonly IUpdateService _updateService;
private readonly IDeleteService _deleteService;
private readonly Policy _policy = ???;
public Connector(ICreateService createService, IUpdateService updateService, IDeleteService deleteService)
{
_createService = createService;
_updateService = updateService;
_deleteService = deleteService;
}
public async Task<CreateResult> CreateAsync()
{
// sample policy: var policy = Policy.Handle<Exception>()
// .OrResult<CreateResult>(r => r.Errors.Contains("EXCEPTION"))
// .Retry();
// Now I need to create such a policy for every call. How can I create a single policy or a factory method to enforce DRY principle?
return _policy.ExecuteAsync(() => _createService.CreateAsync());
}
public async Task<UpdateAsync> UpdateAsync()
{
return _policy.ExecuteAsync(() => _updateService.UpdateAsync());
}
public async Task<DeleteResult> DeleteAsync()
{
return _policy.ExecuteAsync(() => _deleteService.DeleteAsync());
}
}
假设每个 return 类型都有一个 属性 包含 Error
对象的集合,您可以通过让每个策略重用检查该集合的方法来消除一些代码重复。
例如:
public static class PolicyExtensions
{
public static bool ContainsExceptionMessage(this IEnumerable<Error> errors)
{
return errors.Any(error => error.Name.Contains("EXCEPTION"));
}
}
您将需要多个策略,但每个策略都可以重复使用此方法:
var policy = Policy.HandleResult<MyResultClass>(
result => result.Errors.ContainsExceptionMessage())
.Or<Exception>()
.Retry();
如果您的每个 类 实现一个接口,表明它包含错误集合,您还可以创建一个通用函数来 return 策略:
public interface IHasErrors
{
List<Error> Errors { get; }
}
Policy<THasErrors> CreateExceptionPolicy<THasErrors>() where THasErrors:IHasErrors
{
return Policy.HandleResult<THasErrors>(
result => result.Errors.ContainsExceptionMessage())
.Or<Exception>()
.Retry();
}
现在您仍在创建多个策略,但它们更容易创建,并且 none 它们的代码是重复的。
var policy = CreateExceptionPolicy<UpdateResult>();