Friend-Assemblys (C#-Programmierhandbuch)

Aktualisiert: November 2007

Auf einen internen Typ oder einen internen Member in einer Assembly kann von einer anderen Assembly aus zugegriffen werden.

Hinweise

Das Feature der friend-Assemblys ermöglicht Ihnen den Zugriff auf interne Member. Auf private Typen und private Member kann weiterhin nicht zugegriffen werden.

Um einer Assembly (Assembly B) Zugriff auf die internen Typen und Member einer anderen Assembly (Assembly A) zu gewähren, verwenden Sie das InternalsVisibleToAttribute-Attribut in Assembly A.

Hinweis:

Beim Kompilieren einer Assembly (Assembly B), die auf die internen Typen oder internen Member einer anderen Assembly (Assembly A) zugreift, müssen Sie mit der /out-Compileroption explizit den Namen der Ausgabedatei (EXE- oder DLL-Datei) angeben. (Weitere Informationen finden Sie unter /out.) Dies ist notwendig, da der Compiler noch nicht den Namen für die Assembly generiert hat, die er beim Binden an externe Verweise erstellt.

Auch die StrongNameIdentityPermission-Klasse bietet die Möglichkeit, Typen freizugeben. Es bestehen jedoch folgende Unterschiede:

  • StrongNameIdentityPermission gilt für einen einzelnen Typ, während eine friend-Assembly für die ganze Assembly gilt.

  • Wenn Assembly A Hunderte von Typen enthält, auf die Assembly B zugreifen soll, müssen Sie allen Typen eine StrongNameIdentityPermission hinzufügen. Bei Verwendung einer friend-Assembly hingegen müssen Sie die friend-Beziehung nur einmal deklarieren.

  • Bei Verwendung von StrongNameIdentityPermission müssen die Typen, die Sie freigeben möchten, als öffentlich deklariert sein. Bei Verwendung einer friend-Assembly werden die freigegebenen Typen als intern deklariert.

  • Informationen dazu, wie Sie ein .netmodule erstellen können, das auf nicht öffentliche Typen in einer Assembly zugreifen kann, finden Sie unter /moduleassemblyname.

Beispiel

In diesem Beispiel macht die Assembly interne Typen und interne Member für die Assembly cs_friend_assemblies_2 sichtbar.

// cs_friend_assemblies.cs
// compile with: /target:library
using System.Runtime.CompilerServices;
using System;

[assembly:InternalsVisibleTo("cs_friend_assemblies_2")]

// internal by default
class Class1 
{
    public void Test() 
    {
        Console.WriteLine("Class1.Test");
    }
}

// public type with internal member
public class Class2 
{
    internal void Test() 
    {
        Console.WriteLine("Class2.Test");
    }
}

In diesem Beispiel greift die Assembly auf interne Typen und interne Member in der Assembly cs_friend_assemblies.dll zu.

Beachten Sie, dass Sie den Namen der Ausgabedatei (/out:cs_friend_assemblies_2.exe) explizit angeben müssen.

Wenn diese Assembly einer weiteren Assembly (Assembly C) Zugriff auf ihre internen Typen und Member gewährt, wird Assembly C nicht automatisch eine friend-Assembly von Assembly cs_friend_assemblies.dll.

// cs_friend_assemblies_2.cs
// compile with: /reference:cs_friend_assemblies.dll /out:cs_friend_assemblies_2.exe
public class M 
{
    static void Main() 
    {
        // access an internal type
        Class1 a = new Class1();
        a.Test();

        Class2 b = new Class2();
        // access an internal member of a public type
        b.Test();
    }
}

Class1.Test
Class2.Test

In diesem Beispiel wird veranschaulicht, wie interne Typen und Member für Assemblys mit starken Namen verfügbar gemacht werden.

Um die Schlüsseldatei zu generieren und den öffentlichen Schlüssel anzuzeigen, verwenden Sie die folgende Sequenz von sn.exe-Befehlen (weitere Informationen finden Sie unter Strong Name-Tool (Sn.exe)):

  • sn -k friend_assemblies.snk // Schlüssel mit starkem Namen generieren

  • sn -p friend_assemblies.snk key.publickey // Öffentlichen Schlüssel aus key.snk in key.publickey extrahieren

  • sn -tp key.publickey // In Datei key.publickey gespeicherten öffentlichen Schlüssel anzeigen

Übergeben Sie die Schlüsseldatei mit /keyfile an den Compiler.

// cs_friend_assemblies_3.cs
// compile with: /target:library /keyfile:friend_assemblies.snk
using System.Runtime.CompilerServices;

[assembly:InternalsVisibleTo("cs_friend_assemblies_4, PublicKey=0024000004800000940000000602000000240000525341310004000001000100031d7b6f3abc16c7de526fd67ec2926fe68ed2f9901afbc5f1b6b428bf6cd9086021a0b38b76bc340dc6ab27b65e4a593fa0e60689ac98dd71a12248ca025751d135df7b98c5f9d09172f7b62dabdd302b2a1ae688731ff3fc7a6ab9e8cf39fb73c60667e1b071ef7da5838dc009ae0119a9cbff2c581fc0f2d966b77114b2c4")]
class Class1 
{
    public void Test() 
    {
        System.Console.WriteLine("Class1.Test");
    }
}

In diesem Beispiel wird veranschaulicht, wie interne Typen und Member verwendet werden, die für Assemblys mit starken Namen verfügbar sind.

// cs_friend_assemblies_4.cs
// compile with: /keyfile:friend_assemblies.snk /reference:cs_friend_assemblies_3.dll /out:cs_friend_assemblies_4.exe
public class M 
{
    static void Main() 
    {
        Class1 a = new Class1();
        a.Test();
    }
}

Class1.Test

Siehe auch

Konzepte

C#-Programmierhandbuch

Referenz

Assemblys und der globale Assemblycache (C#-Programmhandbuch)