gpt4 book ai didi

c# - 将拦截器添加到现有的 CaSTLe.DynamicProxy 代理

转载 作者:太空宇宙 更新时间:2023-11-03 15:18:00 25 4
gpt4 key购买 nike

假设我有一个由第三方创建的 CaSTLe.DynamicProxy 对象。在本例中是 Rhino.Mocks。

var rhinoObj = MockRepository.GenerateMock<IMyType>();

出于某种原因,我希望能够使用 Rhino 生成的这个对象并向其添加另一个拦截器,这样我就可以在不使用 Rhino 本身的情况下对其进行操作。

我知道这可能看起来很奇怪,它是我自己编写的模拟库,我想与其他使用 CaSTLe 的模拟框架集成,例如 Rhino。

我试过:

 generator.CreateInterfaceProxyWithTarget(rhinoObj, new MyInterceptor())

但是当我想使用诸如 .Stub(..) 之类的东西时,Rhino 会提示说这不是模拟对象 - 很明显 Rhino 拦截器被覆盖了。

最佳答案

我知道这是一个老问题,但我遇到了同样的问题。 2 天前阅读我自己的回答可以节省我几个小时...

问题

Rhino.Mocks 在城堡动态代理的帮助下根据您的接口(interface)生成一个新类型,创建它的实例并将其返回给您。这个实例也被用作 rhino.mock-internal 键来查找所有模拟事物(断言,返回值,...)。

现在您围绕 rhino.mock 对象创建了一个代理(意味着:另一个新类型和另一个新实例),并且按实例查找不再起作用。您以某种方式需要原始对象。

选项 1

你需要保留来自 rhino.mocks 的原始对象。这看起来如何取决于您的整体设置。也许所有实例的创建都通过一个中央存储库,您可以添加像这样的方便的访问器方法:

internal interface IMockRepository
{
void Add(object key, object mock);
T GetMock<T>(T key);
object GetMock(object key);
}

这应该可以解决任何模拟框架,而不仅仅是 rhino.mocks。不利的一面是额外的基础设施和样板代码。还有你的尴尬感觉create a proxy around a proxy .

选项 2

(基于 this 答案):Rhino.mocks 还使用城堡动态代理和拦截器。也许我们可以潜入我们自己的拦截器?我们可以!

var mock = Rhino.Mocks.MockRepository.GenerateStub(type);            
dynamic dyn = mock;
dyn.__interceptors = new[] {new MyInterceptor(), dyn.__interceptors[0]};

您需要使用 CaSTLe.Core.Interceptor 中的 IInterceptor 和 IInvocation 而不是 CaSTLe.DynamicProxy,但接口(interface)是相同的。原始代理必须排在最后。

这依赖于 rhino.mocks-internals,它可能会在未来的任何版本中更改,恕不另行通知。但我认为可以假设 (a) rhino.mocks 将继续使用城堡动态代理,并且 (b) 动态代理将来也将是动态的。所以如果有东西坏了,它应该是可以修复的。

这更“hacky”,但我使用了这个解决方案。没有“代理中的代理”之类的东西,也没有样板文件。

关于c# - 将拦截器添加到现有的 CaSTLe.DynamicProxy 代理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38250061/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com