Background
What is internal access modifier in C#?
Internal modifier allows access to the elements of an assembly, within the same assembly only. This means, if we have one class library type project with two classes Class1 and Class2, any internal classes in it, will be accessible only within this class library project. When we add reference of it's dll in any other project, the internal classes of this library will not be accessible in that project.
By default, class is internal in nature.
So, using internal access modifier is like telling our children not to talk with the strangers. We tell our assembly not to share the internal classes with the stranger assemblies.
Using the code
Access internal members outside the assembly
This was basic about the internal modifier. But suppose we have created a product based library. Now we need to provide access to one of our internal member class to some of our customers and not all of them. Very first thing that will come into our minds is to make the class public. But this will expose the class to all the customers, which they don not even require. Moreover, it results in security vulnerability. This is where the concept of friend assemblies come into the role. We will simply tell our assembly or dll that this class is your friend and you can share your internal members with it. To do this, we just have to add the following line of code on our namespace.
[assembly: InternalsVisibleToAttribute("Name_of_Assembly")]
And that's it. We are done. Build the assembly and we can now access the internal class members as well.
Adding this attribute instructs our assembly to share the details with stranger assemblies. It's like telling our children name of the people with whom they can talk.
An example to access internal members of the class outside the assembly
For this, we will create a new project solution and add two project types - one class library named ClassLibrary and other, console application named Consumer. In class library, we add two classes, one as internal named InternalClass and other as public named PublicClass.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.CompilerServices;
namespace ClassLibrary1
{
internal class InternalClass
{
}
public class PublicClass
{
}
}
Next, we build this project and add its reference in the Consumer project. Then we try to access these two classes in the console application. We will be able to access the public class but not the internal class.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ClassLibrary1;
namespace Consumer
{
class Program
{
static void Main(string[] args)
{
PublicClass _class = new PublicClass();
InternalClass _s = new InternalClass(); }
}
}
Build the code and we get the error 'ClassLibrary1.InternalClass' is inaccessible due to its protection level
Now in order to access the internal class in the console application, we add the InternalsVisibleTo attribute, with the name of the assembly in which we would like to access the internal members. In our case, it is named Consumer. See the code below.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.CompilerServices;
[assembly: InternalsVisibleTo("Consumer")]
namespace ClassLibrary1
{
internal class InternalClass
{
}
public class PublicClass
{
}
}
Build the code and we can now easily access the internal members. In this way, we can add as many assembly names, as we need.
Points of Interest
So this all what we had to do to allow access to internal classes. We can add multiple attributes, with the names of the assemblies with which we would like to share these internal classes. But the condition here is that we need to add this attribute at the namespace level. Hope you enjoyed reading it...!!!