Accessing internal classes
Hi,
I am trying to access an internal class in another assembly. For example, Assembly1(in a dll) has some internal classes. I am creating Assembly2 and need to access the internal classes in Assembly1. Can anyone advice me as to how this can be done? I cannot change any attributes of Assembly1 as it is inside a dll file.
Thanks in advance.
Anjali
AlanPosted Oct 15, 2008, 12:08 PM
One other point which I just remembered today.
If the programmer of the dll wants to make its internal types and members accessible to one (or more) specific assemblies, then (s)he can do so by including the InternalsVisibleTo attribute within the dll.
Check out the following link for more details on this feature which is known as 'friend assemblies' and is available from .NET 2.0 onwards:
http://msdn.microsoft.com/en-us/library/0tke9fxk.aspx
AlanPosted Oct 12, 2008, 5:59 AM
Although in my earlier example the method being called had no return value, the MethodInfo.Invoke() method returns an object which you can cast to the appropriate type.
If a class has a static constructor, then this is called automatically as soon as a class is first instantiated or a static member of that class is accessed. You can't call a static constructor directly, either normally or by reflection, and there is never a need to do so.
The following revision of my example will make these points clear:
// mytest.dll
using System;
namespace MyTest
{
internal class MyClass
{
internal static int myInt = 0;
static MyClass()
{
myInt = 42;
}
internal string MyMethod()
{
Console.WriteLine("The value of MyInt is " + myInt.ToString());
return "This is a message returned from MyTest.MyClass!";
}
}
}
// executable
using System;
using System.Reflection;
namespace MyProgram
{
class MyProgram
{
static void Main()
{
Assembly assembly = Assembly.LoadFrom("mytest.dll");
object mc = assembly.CreateInstance("MyTest.MyClass");
Type t = mc.GetType();
BindingFlags bf = BindingFlags.Instance | BindingFlags.NonPublic;
MethodInfo mi = t.GetMethod("MyMethod", bf);
string result = (string)mi.Invoke(mc, null);
Console.WriteLine(result);
Console.ReadKey();
}
}
}
Incidentally, although it's possible to discover information about a non-public method's parameters and return type using reflection as well (or by using a utility such as .NET Reflector), I'm assuming that you already have this information. It is, of course, dangerous to call any method (particularly an undocumented non-public one) without knowing what it does as, for all you know, it could delete files without warning or do other undesirable things to the system.
Anjali RPosted Oct 11, 2008, 8:29 PM
AlanPosted Oct 11, 2008, 6:18 PM
Despite what Scott says, unless permission to access non-public members using reflection has been denied by the programmer, you can access internal classes within another assembly using reflection.
Here's a very simple example.
Suppose you have this dll (mytest.dll say):
using System;
namespace MyTest
{
internal class MyClass
{
internal void MyMethod()
{
Console.WriteLine("Hello from MyTest.MyClass!");
}
}
}
and you want to create an instance of MyTest.MyClass and then call MyMethod() from another program using reflection. Here's how to do it:
using System;
using System.Reflection;
namespace MyProgram
{
class MyProgram
{
static void Main()
{
Assembly assembly = Assembly.LoadFrom("mytest.dll");
object mc = assembly.CreateInstance("MyTest.MyClass");
Type t = mc.GetType();
BindingFlags bf = BindingFlags.Instance | BindingFlags.NonPublic;
MethodInfo mi = t.GetMethod("MyMethod", bf);
mi.Invoke(mc, null);
Console.ReadKey();
}
}
}
Scott LyslePosted Oct 11, 2008, 12:08 PM
That is the purpose of an internal class; you can't access from outside the assembly.