2

Let's say I have a Castle.DynamicProxy object that is created by a third party. In this case Rhino.Mocks.

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

For one reason or another I want to be able to use this generated object by Rhino and add another interceptor to it so I can manipulate it without using Rhino itself.

I understand this may seem weird, its for a mocking library I'm writing myself that I want integrated with other mocking frameworks that use Castle, such as Rhino.

I have tried:

 generator.CreateInterfaceProxyWithTarget(rhinoObj, new MyInterceptor())

But Rhino complains when I wish to use anything such as .Stub(..) that this is not a mocked object - so clearly the rhino interceptors are overwritten.

PatrickSteele
  • 14,489
  • 2
  • 51
  • 54
MartinM
  • 1,736
  • 5
  • 20
  • 33
  • 1
    Have you looked at the [Rhino.Mocks source code](https://github.com/ayende/rhino-mocks) to see what conditions make the `Stub` method complain? Might give you some insight into the issue. – PatrickSteele Jul 12 '16 at 12:27
  • 1
    Yes, It seems that Rhino keep hold of references to proxies/mocks they produce. So if somebody else creates it, it can't do anything with it. Sadly I don't think my plan is possible! – MartinM Aug 24 '16 at 08:41

1 Answers1

0

I know it is an old question but I had the same problem. Reading my own answer 2 days ago would have saved me several hours...

The Problem

Rhino.Mocks with the help of castle dynamic proxy generates a new type based on your interface, creates an instance of it and returns it to you. This instance is also used as a rhino.mock-internal key to look up all mocking-things (assertions, return values, ...).

Now you create a proxy (means: another new type and another new instance) around the rhino.mock-object and the lookup-by-instance does not work anymore. You need the original object somehow.

Option 1

You need to keep the original object from rhino.mocks around. How this will look depends on your overall setup. Maybe all instances creation goes through a central repository and you can add handy accessor methods like those:

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

This should the trick any mocking framework, not just rhino.mocks. On the minus-side is extra infrastructure and boilerplate code. And the akward feeling that you create a proxy around a proxy.

Option 2

(based on this answer): Rhino.mocks also uses castle dynamic proxies and interceptors. Maybe we can sneak in our own interceptor? We can!

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

You need to use IInterceptor and IInvocation from Castle.Core.Interceptor instead of Castle.DynamicProxy but the interfaces are identical. The original proxy must come last.

This relies on rhino.mocks-internals which might change in any future release without notice. But I think it is save to assume that (a) rhino.mocks will continue to use castle dynamic proxies and (b) dynamic proxies will be dynamics also in future. So if something breaks, it should be fixable.

This is more "hacky" but I use this solution. No "proxy-of-proxy"-thing and no boilerplate.

Peter Schneider
  • 1,683
  • 12
  • 31