Condividi tramite


Assembly friend (Guida per programmatori C#)

Aggiornamento: novembre 2007

È possibile accedere a un tipo interno o a un membro interno di un assembly da un altro assembly.

Note

La funzionalità degli assembly friend consente di accedere ai membri interni. I tipi e i membri privati rimangono invece inaccessibili.

Per fornire a un assembly (assembly B) l'accesso ai tipi e ai membri interni di un altro assembly (assembly A), utilizzare l'attributo InternalsVisibleToAttribute nell'assembly A.

Nota:

Quando si compila un assembly (assembly B) che accederà ai tipi o ai membri interni di un altro assembly (assembly A), è necessario specificare in modo esplicito il nome del file di output (exe o dll) con l'opzione del compilatore /out (per ulteriori informazioni, vedere /out), perché il compilatore non ha ancora generato il nome dell'assembly che sta generando nel momento in cui esegue l'associazione a riferimenti esterni.

Anche la classe StrongNameIdentityPermission consente di condividere tipi, con le seguenti differenze:

  • StrongNameIdentityPermission si applica a un singolo tipo, mentre un assembly friend è valido per l'intero assembly.

  • Se l'assembly A contiene centinaia di tipi che si desidera condividere con l'assembly B, è necessario contrassegnarli tutti con StrongNameIdentityPermission, mentre utilizzando un assembly friend è necessario dichiarare la relazione friend una sola volta.

  • Utilizzando StrongNameIdentityPermission i tipi da condividere devono essere dichiarati come pubblici. Utilizzando un assembly di tipo friend, i tipi condivisi vengono dichiarati come interni.

  • Per informazioni sulla compilazione di un assembly .netmodule in grado di accedere ai tipi non pubblici di un assembly, vedere /moduleassemblyname.

Esempio

Nell'esempio riportato di seguito l'assembly rende visibili i tipi e i membri interni all'assembly denominato cs_friend_assemblies_2.

// 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");
    }
}

Nell'esempio riportato di seguito l'assembly utilizza i tipi e i membri interni nell'assembly cs_friend_assemblies.dll.

Si noti che è necessario specificare in modo esplicito il nome del file di output (/out:cs_friend_assemblies_2.exe).

Se questo assembly fornisce a un altro assembly (assembly C) l'accesso ai propri tipi e membri interni, l'assembly C non diventa automaticamente friend dell'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

Nell'esempio riportato di seguito viene illustrato come rendere disponibili i tipi e i membri interni per gli assembly con nomi sicuri.

Per generare il file di chiavi e visualizzare la chiave pubblica, utilizzare la seguente sequenza di comandi sn.exe (per ulteriori informazioni, vedere Strumento Nome sicuro (Sn.exe)):

  • sn -k friend_assemblies.snk // Generate strong name key

  • sn -p friend_assemblies.snk key.publickey // Extract public key from key.snk into key.publickey

  • sn -tp key.publickey // Display public key stored in file'key.publickey

Passare il file di chiavi al compilatore con /keyfile.

// 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");
    }
}

Nell'esempio riportato di seguito viene illustrato come utilizzare i tipi e i membri interni disponibili per gli assembly con nomi sicuri.

// 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

Vedere anche

Concetti

Guida per programmatori C#

Riferimenti

Assembly e Global Assembly Cache (Guida per programmatori C#)