If at first you don't succeed, call it version 1.0

Contact Me

Sarvesh Kushwaha
Email : sarveshkushwaha@outlook.com

Total Pageviews

Powered by Blogger.

Google+ Followers

Thursday, 26 January 2017

How to acess INTERNAL types and members into another assembly ? #AspNetInterviewQuestionsSeries


Lets learn about INTERNAL keyword in C#. Basically INTERNAL keyword is an access modifier which ensures that types and members within the same assembly. 

But is there any way we can access the INTERNAL  type and members from another assembly? 

yeah there is actually. We can use  the INTERNALVISIBLETO keyword into assmeblyinfo.cs or onto the class at namespace level using System.Runtime.CompilerServices.

Lets Code :

I have created two projects into a solution so we can have two diff assembly.






















as you can see above i have created an internal class and  a internal member method.
Code :

namespace ConsoleApplication3
{
    
    internal class Program
    {
        static void Main(string[] args)
        {
        }

        internal static int calculateLength(string s)
        {

            return s.Length;
        }
    }
}

now what i have done is added this consoleapplication3 assembly as a reference in my consoleapplication1 .  But if i am trying to access the class program of consoleapplication3 in consoleapplication1 i receive a compile time error i.e "Program' is inaccessible due to its protection level" .



To access the internal class and its internal member we can use INTERNALVISIBLETO  as follows;

Solution 1 : add INTERNALVISIBLETO  assemblyinfo.cs file 


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

// General Information about an assembly is controlled through the following 
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("ConsoleApplication3")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("ConsoleApplication3")]
[assembly: AssemblyCopyright("Copyright ©  2017")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
[assembly: InternalsVisibleTo("ConsoleApplication1")]



Solution 2 : Add it at namespace level in class using System.Runtime.CompilerServices;


using System.Runtime.CompilerServices;

[assembly: InternalsVisibleTo("ConsoleApplication1")]
namespace ConsoleApplication3
{
    
    internal class Program
    {
        static void Main(string[] args)
        {
        }

        internal static int calculateLength(string s)
        {

            return s.Length;
        }
    }
}

Solution 3 : We can use reflection to achieve this :

using System;
using System.Linq;
using System.Reflection;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            var type = Assembly.Load("ConsoleApplication3").GetTypes().First(x => x.Name.Equals("Program", StringComparison.Ordinal));
            var methods = type.GetMethods();
            MethodInfo dynMethod = type.GetMethod("calculateLength", BindingFlags.NonPublic | BindingFlags.Static);
            dynamic result = null;
            if (dynMethod != null)
            {
                ParameterInfo[] parameters = dynMethod.GetParameters();
                object classInstance = Activator.CreateInstance(type, null);
                object[] parametersArray = new object[] { "Hello" };
                result = dynMethod.Invoke(classInstance, parameters.Length == 0 ? null : parametersArray );
            }
          
           // int a = ConsoleApplication3.Program.calculateLength("gfgfgffg");
            Console.ReadLine();
        }
    }
}

I think we should use this INTERNALVISIBLETO attribute when we have to create unit test assemblies that are allowed to call internal members of internal assemblies to be tested.
Reactions:

0 comments:

Post a Comment