views:

852

answers:

5

I have a class whose constructor is defined as internal, which means I cannot instantiate it. While that may make sense, I would still like to do it once for debugging and research purposes.

Is it possible to do so with Reflection? I know I can access Private/Internal Members, but can I call an internal constructor?

Or, as the constructor does nothing important, can I use reflection to say "Look, just give me an instance of the class without calling the constructor, I'll do it's work manually"?

Performance and "Stability" is not an issue here, as it's not production code.

Edit: Just as clarification: Sadly, I don't control the other assembly and don't have it's source code, I merely try to understand how it works as it's documentation is next to non-existent, but I am supposed to interface with it.

+6  A: 

An alternative would be to nominate the calling assembly as a "friend" assembly.

Simply add this to AssemblyInfo.cs file of the assembly containing the internal constructor:

[assembly: InternalsVisibleTo("Calling.Assembly")]


If you don't have access to the assembly, you can also call the constructor directly (using Reflection):

MyClass obj = (MyClass) typeof(MyClass).GetConstructor(
                  BindingFlags.NonPublic | BindingFlags.Instance,
                  null, Type.EmptyTypes, null).Invoke(null);
Philippe Leybaert
Sadly I don't control the other assembly :(
Michael Stum
Edited my answer to include a solution using reflection
Philippe Leybaert
For some reason, GetContructor returns null, even when experimenting with the BindingFlags. But generally it's an helpful answer, so +1 to that.
Michael Stum
A: 

internal doesn't mean that you can't instantiate it. It just means that only members from the same assembly may call it.

For test purposes you can allow your test assembly to access internals as well using the InternalsVisibleTo attribute. See http://msdn.microsoft.com/en-us/library/system.runtime.compilerservices.internalsvisibletoattribute.aspx

Brian Rasmussen
Er.. what if you want to instantiate it from another assembly. Then you can't....
ck
Correct, unless you can use the InternalsVisibleTo. With the update to the question that doesn't seem to be the case, but that was not clear to me from the original wording.
Brian Rasmussen
+3  A: 

A FormatterService.GetUninitializedObject method exists, it supposedly calls no constructors, if you really want to try out that approach.

kek444
This and Type.GetField()/FieldInfo.SetValue solved my problem.
Michael Stum
A: 

You could use Reflector to analyse its source code and from that figure out the inner workings.

Peter Lillevold
+2  A: 

I experienced this same situation a while back and created a small utility I called "InternalsVisibleToInjector". It uses ILDASM and ILASM to disassemble, modify, and reassemble and assembly with the assembly name of my selection added to the InternalsVisibleTo list for the target assembly. It worked quite well in my situation.

I have posted the source code (VS 2008 C# WinForm) for the utility here:

http://www.schematrix.com/downloads/InternalsVisibleToInjector.zip

This may not work if the assembly is signed. Please take all appropriate precautions (i.e. make a backup of the assembly before using this and ensure you are on solid legal ground, etc.)

Michael McCloskey