W sporadycznych przypadkach chcemy udostępnić klasy lub metody z modyfikatorem internal wybranym projektom(assembly).
Do tego celu służy atrybut :

[assembly: InternalsVisibleTo("Frendly_assembly_name")]

Umieszczamy go przed dowolnym namespace w projekcie, którego elementy z modyfikatorem dostępu internal mają być widoczne w wybranych assembly.

Użycie atrybutu InternalsVisibleTo wymaga odwołania do System.Runtime.CompilerServices;

I tak naprawdę to tyle. Nic skomplikowanego a może znacznie uprościć życie.

Atrybut InternalsVisibleTo, może być przykładowo przydatny do udostępnienia projektowi z testami elementów z atrybutem internal w celu ich przetestowania.

Poniżej zamieszczę prosty przykład użycia atrybutu InternalsVisibleTo:

Stwórzmy solucje z trzema projektami:

Rys 1. Moduły w solucji

Następnie ustawmy nazwę dla assembly dla projektu Test.
Aby to zrobić klikamy prawym przyciskiem myszy na projekt i z menu kontekstowego wybieramy opcję Propierties.

Rys 2. Menu kontekstowe dla modułu Test

W wyświetlonym oknie w polu Assembly name wpiszmy nazwę „Friend”. Jest to nazwa naszego assembly po skompilowaniu.

Rys 3. Ustawienia dla projektu Test

Dodajmy następnie referencję Pisz-Kod-Ninja do projektu Test.

Rys 4. Referencje modułu Test

W sposób analogiczny postąpimy z dodaniem referencji Pisz-Kod-Ninja do projektu Pisz-Kod.

Rys 5. Referencje modułu Pisz-Kod

Napiszemy teraz klasę w projekcie Pisz-kod-Ninja o modyfikatorze dostępu internal i nazwie VeryHiddenNinja. W niej stwórzmy metodę GetHiddenText():

namespace Pisz_Kod_Ninja
{
    internal class VeryHiddenNinja
    {
        public string GetHiddenText()
        {
            return "hiden... hiden...";
        }
    }
}

Następnie w projekcie Pisz-Kod spróbujmy stworzyć obiekt klasy VeryHiddenNinja
using Pisz_Kod_Ninja;

namespace Pisz_Kod
{
    public class SuperClass
    {
        public void TestHiddenNinja()
        {
            var veryHiddenNinja = new VeryHiddenNinja();
        }
    }
}

Klasa VeryHiddenNinja ma modyfikator dostępu internal  nie dodaliśmy atrybutu InternalsVisibleTo dla projektu Pisz-Kod więc kompilator zgłasza nam oczywisty błąd.

Rys 6. Błąd zgłoszony przez kompilator

Na początku artykułu zmieniłem nazwę assembly dla projektu Test. Nazywa się ono teraz Friend. Użyjmy atrybutu InternalsVisibleTo w  projekcie Pisz-Kod-Ninja dla assembly Frend.

using System.Runtime.CompilerServices;
[assembly: InternalsVisibleTo("Friend")]
namespace Pisz_Kod_Ninja
{
    internal class VeryHiddenNinja
    {
        public string GetHiddenText()
        {
            return "hiden... hiden...";
        }
    }
}

Zobaczmy czy jesteśmy w stanie użyć teraz klasy VeryHiddenNinja w projekcie Test:

using System;
using Pisz_Kod_Ninja;
namespace Test
{
  public class Program
    {
        static void Main()
        {
            var hiddenClass = new VeryHiddenNinja();

            Console.WriteLine(hiddenClass.GetHiddenText());
            Console.ReadKey();
        }
    }
   
}

Visual studio nie zgłasza błędu więc uruchommy naszą prostą aplikację:

Rys 7. Rezultat działania aplikacji

Udało się. Udostępniliśmy klasę z modyfikatorem dostępu internal innemu assembly:)