如何包装实例并将调用转发给包装的实例成员



假设我有一个这样的包装实例,Resolve方法在其中注入依赖项

var handler = this.Resolve<DeletePaymentCardHandler>();
var wrapperHandler = A.Fake<DeletePaymentCardHandler>(
o => o.Wrapping(handler));

A.CallTo(() => wrapperHandler.EnsurePaymentCardCanBeDeleted(A<DeletePaymentCard>._, A<CancellationToken>._ ))
.Returns(Task.CompletedTask);

await wrapperHandler.Handle(command, CancellationToken.None);

"句柄"方法的实现方式与类似

public async Task Handle(DeletePaymentCard msg, CancellationToken cancellationToken)
{
await this.EnsurePaymentCardCanBeDeleted(msg, cancellationToken);
var instance = await this.repository.GetById<Domain.CustomerFundingSources>(msg.CustomerId, cancellationToken);
instance.Process(msg);
await this.repository.Save(instance);
}
public virtual async Task EnsurePaymentCardCanBeDeleted(DeletePaymentCard command, CancellationToken cancellationToken)
{
return Task.CompletedTask
}

我观察到的是,Handle中的这个调用不是调用注入的存储库,而是调用FakeIseasy创建的代理?

var instance = await this.repository.GetById<Domain.CustomerFundingSources>(msg.CustomerId, cancellationToken);

我认为重点是能够只拦截对某些方法的调用,而其余的应该调用封装的实例方法?来自文件:

"默认情况下,对未显式进行包装的伪调用配置的将被转发到被包装的对象">

如果不访问DeletePaymentCardHandler的所有代码,就不可能完全确定,但对我来说,这是什么样子:

Handle不是虚拟的,因此将执行DeletePaymentCardHandler中的代码,完全绕过FakeIseasy。

Handle中,GetById方法在repository字段上调用(访问repository不是方法调用,FakeIseasy无法拦截字段访问(,该字段很可能已由伪造的DeletePaymentCardHandler类的构造函数初始化。

如果repository字段是从构造函数参数初始化的,FakeItEasy将提供一个Dummy存储库来满足该构造函数参数。存储库类型很可能是FakeIseasy可以伪造的,因此该值将是fake。

因此,在wrappedHandler.Handle中,真实的Handle代码正在调用伪repository

如果您想要一些其他行为,那么可能需要为fake提供与包装处理程序相同的存储库。或者,Handle可以通过虚拟属性或方法访问存储库,该虚拟属性或方式将被FakeItEasy拦截并转发给包装的处理程序,然后该处理程序将访问Resolve方法提供的存储库。

最新更新