castleproject/Core — pull request #21 by tailsu (2013-03-19 12:32:44+00:00)
Title: Creating proxies for classes with inaccessible constructors

Hey guys,

For our mocking needs our team needed to be able to create mocks of classes that didn't have a visible constructor. It turns out that it is, in fact, possible to do so. It's barely legal code, but you may skip calling the base constructor from a dynamically generated constructor in the proxy. The generated code fails verification in PEVerify and requires full trust, but **it works**! That's what was important in our case, anyway. The base class remains zero-initialized, as if from a call to FormatterServices.GetUninitializedObject().

Another feature we wanted was for proxy constructors to not be called through reflection, so that exceptions thrown in the constructor didn't get wrapped in a TargetInvocationException and didn't lose their call stack. We implemented this by calling the constructor from an expression-derived lambda. Incidentally, we also got proxy constructor overload resolution to work property and got 2 ignored tests to run. We also allow the user to generate a default constructor in the proxy, even if the base type doesn't have a default constructor - also very useful for mocking.

The pull request contains:
* the code for bypassing base constructors
* tests for the bypassing - the tests themselves run successfully, but PEVerify fails in the tear-down.
* the code for calling the proxy constructor from a dynamically generated lambda, instead of through Activator.CreateInstance() and a test for an exception thrown from a constructor.

Please, share your thoughts about the two features and their implementation. I've tested the code in NET35; I'm not sure how to test it for the rest of the platforms.

P.S.
I'm sure that the Moq user base would be delighted if the first feature were to be included :)

http://stackoverflow.com/questions/3279412/mocking-a-type-with-an-internal-constructor-using-moq
http://stackoverflow.com/questions/7361483/partial-mock-of-a-class-with-private-constructor
http://stackoverflow.com/questions/2976018/use-moq-to-mock-constructor
etc.