Поделиться через


Дружественные сборки (руководство по программированию на C#)

Обновлен: Ноябрь 2007

Доступ к внутреннему типу или внутреннему члену сборки может осуществляться из другой сборки.

Заметки

Дружественные сборки позволяют осуществлять доступ к внутренним членам. Закрытые типы и закрытые члены останутся недоступными.

Чтобы предоставить сборке (сборка B) доступ к внутренним типам и членам другой сборки (сборка A), используйте атрибут InternalsVisibleToAttribute в сборке A.

0tke9fxk.alert_note(ru-ru,VS.90).gifПримечание.

При компиляции сборки (сборка B), которая будет осуществлять доступ к внутренним типам и членам другой сборки (сборка A), необходимо явным образом указать имя итогового файла (EXE или DLL) с помощью параметра компилятора /out (дополнительные сведения см. в разделе /out). Это необходимо, потому что компилятор еще не создал имени конструируемой сборки в момент выполнения привязки к внешним ссылкам.

Класс StrongNameIdentityPermission также предоставляет возможность совместного использования типов, но со следующими отличиями.

  • StrongNameIdentityPermission применяется к отдельному типу, а дружественная сборка применяется ко всей сборке.

  • Если в сборке A содержатся сотни типов, которые необходимо совместно использовать со сборкой B, потребуется оформить все эти типы классом StrongNameIdentityPermission, а при использовании дружественной сборки требуется только объявить один раз отношение дружественности.

  • При использовании StrongNameIdentityPermission типы, которые необходимо совместно использовать, должны быть объявлены как открытые. При использовании дружественной сборки общие типы объявляются как внутренние.

  • Сведения о создании файла NETMODULE, имеющего доступ к типам сборки, которые не являются общими, см. в разделе /moduleassemblyname.

Пример

В этом примере сборка делает внутренние типы и внутренние члены видимыми для сборки с именем "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");
    }
}

В этом примере сборка использует внутренние типы и внутренние члены сборки "cs_friend_assemblies.dll".

Обратите внимание, что необходимо явным образом указать имя итогового файла (/out:cs_friend_assemblies_2.exe).

Если эта сборка предоставит другой сборке (сборка С) доступ к своим внутренним типам и членам, сборка С не станет автоматически дружественной к сборке "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

В этом примере показано предоставление доступа к внутренним типам и членам для сборок, имеющих строгие имена.

Используйте следующую последовательность команд sn.exe, чтобы создать файл ключа и отобразить открытый тип (дополнительные сведения см. в разделе Средство строгих имен (Sn.exe)).

  • sn -k friend_assemblies.snk // Создание ключа для строгого имени

  • sn -p friend_assemblies.snk key.publickey // Извлечение открытого ключа из key.snk в key.publickey

  • sn -tp key.publickey // Отображение открытого ключа, сохраненного в файле'key.publickey

Передайте файл ключа компилятору с помощью параметра /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");
    }
}

В этом примере показано использование внутренних типов и членов, которые доступны для сборок, имеющих строгие имена.

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

См. также

Основные понятия

Руководство по программированию в C#

Ссылки

Сборки и глобальный кэш сборок (Руководство по программированию на C#)