views:

1771

answers:

4

Duplicate of:
Accessing internal members via System.Reflection?


Is there a way to execute "internal" code via reflection?

Here is an example program:

using System;
using System.Reflection;

namespace ReflectionInternalTest
{
    class Program
    {
        static void Main(string[] args)
        {
            Assembly asm = Assembly.GetExecutingAssembly();

            // Call normally
            new TestClass();

            // Call with Reflection
            asm.CreateInstance("ReflectionInternalTest.TestClass", 
                false, 
                BindingFlags.Default | BindingFlags.CreateInstance, 
                null, 
                null, 
                null, 
                null);

            // Pause
            Console.ReadLine();
        }
    }

    class TestClass
    {
        internal TestClass()
        {
            Console.WriteLine("Test class instantiated");
        }
    }
}

Creating a testclass normally works perfectly, however when i try to create an instance via reflection, I get a missingMethodException error saying it can't find the Constructor (which is what would happen if you tried calling it from outside the assembly).

Is this impossible, or is there some workaround i can do?

+1  A: 

Duplicate of this

Preet Sangha
Thank you for the pointer. I addedusing System.Runtime.CompilerServices;[assembly: InternalsVisibleTo("System.Reflection.Assembly")]below the last using line, however it still cannot find the constructor. I also tried ReflectionInternalTest.Program, but neither worked. What am i supposed to expose the internals to?
cyberconte
Ahh. i was also missing the additional Bindingflags.
cyberconte
Good dupe catch.. you should mark the question with a dupe header.. which seems to be the new 'defacto' approach. Did that for you here..
Gishu
i dont know how to do that.
Preet Sangha
A: 

Here is an example ...

  class Program
    {
        static void Main(string[] args)
        {
            var tr = typeof(TestReflection);

            var ctr = tr.GetConstructor( 
                BindingFlags.NonPublic | 
                BindingFlags.Instance,
                null, new Type[0], null);

            var obj = ctr.Invoke(null);

            ((TestReflection)obj).DoThatThang();

            Console.ReadLine();
        }
    }

    class TestReflection
    {
        internal TestReflection( )
        {

        }

        public void DoThatThang()
        {
            Console.WriteLine("Done!") ;
        }
    }
JP Alioto
A: 

Based on Preets direction to an alternate post:

using System;
using System.Reflection;
using System.Runtime.CompilerServices;

namespace ReflectionInternalTest
{
    class Program
    {
        static void Main(string[] args)
        {
            Assembly asm = Assembly.GetExecutingAssembly();

            // Call normally
            new TestClass(1234);

            // Call with Reflection
            asm.CreateInstance("ReflectionInternalTest.TestClass", 
                false, 
                BindingFlags.Default | BindingFlags.CreateInstance | BindingFlags.Instance | BindingFlags.NonPublic, 
                null, 
                new Object[] {9876}, 
                null, 
                null);

            // Pause
            Console.ReadLine();
        }
    }

    class TestClass
    {
        internal TestClass(Int32 id)
        {
            Console.WriteLine("Test class instantiated with id: " + id);
        }
    }
}

This works. (Added an argument to prove it was a new instance).

turns out i just needed the instance and nonpublic BindingFlags.

cyberconte
A: 

Use the AccessPrivateWrapper dynamic wrapper if you are in C# 4.0 http://amazedsaint.blogspot.com/2010/05/accessprivatewrapper-c-40-dynamic.html

amazedsaint