2014-04-30 55 views
0

我有一个域服务需要应用一些影响基础设施层的规则,因为它们是域需求。简而言之:基础设施政策&策略。域服务中的基础设施问题

public MyService : IMyService { 

    private readonly RetryPolicy<ConnectionErrorDetectionStrategy> _retryPolicy; 
    // there might be other strategies for other concerns 
    private readonly IRepository _repository; 

    public MyService(IRepository repository) { 
     _repository = repository; 
     _retryPolicy = new RetryPolicy<ConnectionErrorDetectionStrategy>(); 
    } 

    public Do() { 

     _repository.CrudMagic(); 
     _retryPolicy.ExecuteAction(() => _repository.Commit()); 

    } 

} 

要求是为了确保在某些情况下(情况),软件应在应用程序失败(政策)连接到数据库进行多次重试(战略)。然而,这感觉很尴尬,因为域名不知道连接是什么(整个DAL甚至可能是模拟!)。我怎样才能确保正确的策略适用于这种特定的服务/案例?

回答

0

使用代理或装饰。

class MyService : IMyService {...} 
class MyRetryService: IMSyService { 
    private readonly IMSyService target; //inject MyService 
    private readonly RetryPolicy<ConnectionErrorDetectionStrategy> _retryPolicy; 
} 

当单元测试时将模拟注入目标(IMSyService)。只需期待并验证目标的调用。如果失败已经发生并且重试有效,则应该按照指定的策略多次调用目标。

另一种方法是AOP(如果您的平台上有成熟的框架/ lib)。测试方法是一样的。

+0

“*应该多次调用目标*”你是怎么说的? RetryPolicy是一个有状态的应用程序层服务,它可以自动重复某个动作,例如,抛出异常。如果我将调用目标(IMyService.Do())的次数与策略中指定的次数一样多,我最终会在数据库中有x个条目(或者由于实体已存在,甚至会有更多的异常)。 – Acrotygma

+0

此外,从Do()分离所需的操作(commit())并将其放在接口上也是错误的,因为我的服务不允许客户端提交。提交只是客户操作的一部分。 – Acrotygma

+0

当出现问题时,RetryPolicy的目标是在预定义的时间重试某些操作吗?如果一切正常,只执行一次该操作? – Hippoom