How to use internal class of another Assembly

24,129

Solution 1

internal: The type or member can be accessed by any code in the same assembly, but not from another assembly.

You can not use internal classes of other assemblies, the point of using internal access modifier is to make it available just inside the assembly the class defined.

if you have access to the assembly code and you can modify it you can make second assembly as a friend of your current assembly and mark the assembly with following attribute

[assembly: InternalsVisibleTo("name of assembly here")]

if not you can always use reflection but be aware that using reflection on a 3rd party assembly is dangerous because it is subject to change by the vendor. you can also decompile the whole assembly and use part of the code you want if it is possible.

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(); 
         } 
    } 
}  

Solution 2

If you're unable to modify and recompile the library, have a look at ImpromptuInterface.

https://www.nuget.org/packages/ImpromptuInterface/

Example:

namespace ImpromptuExample
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            // Get the desired type
            Type typeObject = typeof(SampleLibrary.PublicClass).Assembly.GetType("SampleLibrary.SamplePrivateClass");
            // todo:  add error handling if typeObject is null

            // Create an instance
            object instance = Activator.CreateInstance(typeObject);
            ITest wrappedInstance = ImpromptuInterface.Impromptu.ActLike<ITest>(instance);
            MessageBox.Show(wrappedInstance.TestMethod(textBox1.Text));
        }

        public interface ITest
        {
            string TestMethod(string name);
        }
    }
}

namespace SampleLibrary
{
    public class PublicClass
    {
    }

    class SamplePrivateClass
    {
        public string TestMethod(string name)
        {
            return string.Concat("Hello ", name);
        }
    }
}

Internally, what ImpromptuInterface does is to create a dynamic assembly in memory and within that assembly, it creates a proxy class which implements the requested interface(s) and relays method calls and properties between the two. In the back end it still uses reflection but it is a slightly nicer encapsulation than doing it all through your own reflection.

Obviously there is an overhead involved with this but it is a viable last resort if you have no other option.

Useful features, include: the dynamic proxy class maps properties to fields, you can map interface methods to private, protected and internal methods in the original class. It doesn't work with static classes of methods, however.

Solution 3

You must create a friendly assembly, but you would need to recompile that third party assembly:

A friend assembly is an assembly that can access another assembly's Friend (Visual Basic) or internal (C#) types and members. If you identify an assembly as a friend assembly, you no longer have to mark types and members as public in order for them to be accessed by other assemblies.

You can use reflection though: How to access internal class using Reflection

Not recommendable anyway.

Solution 4

If it is an internal class, then the developer does not want you to use it. If you want to use a part of this code, just use Reflector and move it to a new class. It is not safe to use internal or private classes because the developer is not thinking of anyone other than themselves using it, and they could make changes in the future that break the functionality, they may not be thread safe, etc. So you should just respect their design.

Solution 5

You cannot do that. Have look here: Accessibility Levels (C# Reference)

Share:
24,129
user1878422
Author by

user1878422

Updated on October 05, 2020

Comments

  • user1878422
    user1878422 over 3 years

    I have a third party assembly and I would like to use its Internal class in my new C# project. Is it possible?

    Any example would really be appreciated