Scattered throughout the .NET framework are classes that are intended to appear externally sealed, but internally (by the framework class library developers) open for further extension. Because there is no mechanism to only allow classes to be sealed outside of the current assembly, framework developers at Microsoft use a compensating pattern: internal constructors.
Unfortunately, this has a side effect of making the classes uninstantiable. For the most part, this is not a problem as these classes are given to the developer already instantiated and ready to be consumed.
(System.Diagnostics.DataReceivedEventArgs as seen in Reflector. A good example of an example of internal constructor being used in the .NET framework FCL )
A practical example – What about mocking?
Mocking framework objects is the most common case where the internal constructor pattern causes an inconvenience. For the sake of example, image that you intend to test an event handler you just created that consumes DataReceivedEventArgs:
You may try creating a unit test that passes in a custom DataReceivedEventArgs object with different data strings. Such as:
Unfortunately, you quickly realize that DataReceivedEventArgs can’t be instantiated:
(Actually a lie, DataReceivedEventArgs has a constructor defined but it’s just marked as “Internal”)
One plain solution to this problem would be to decouple your implementation of processing new error data from the event notification. Something like:
Now, you can test the implementation freely. This is a completely valid way to sidestep the uninstantiable object issue with testing.
Of course, you’ve just paid for your new ability with an entirely new method and a minimum of four new lines of code to maintain. Following this pattern with many events could add up to a significant maintenance cost down the road.
Instantiating the Uninstantiable
An alternative to changing your implementation is to use a mixture of reflection and serialization helper methods to create your target object without calling any constructors, and then manually set its private/internal fields.
Yes, you heard me correctly, create an object without calling any constructors.
This is not only possible, but easy (about one line of code in c#), believe it or not! Simply call GetUninitializedObject. Let me show you an example:
(Creates a new DataReceivedEventArgs object called MockEventArgs)
The first thing you should be concerned about is plugging in some values for the private fields, which will be null and performing any critical rolls the constructor would have.
I strongly recommend studying the constructor of your target object in a tool such as Reflector, before initializing it yourself.
Here’s an example of setting the (single) internal field on MockEventArgs:
That’s it! Now the MockEventArgs object can be used just as if it came from inside the framework and your test method can emulate the event:
Making it Reusable
Obviously typing out this code every time you needed to mock up an uninstantiable object would be a major headache. I packaged these into a neat set of methods that makes it easy to mock up these difficult objects in only a few lines of code. Here’s the finished product:
(Updated on August 31st)