Дружественные сборки (руководство по программированию на C#)
Обновлен: Ноябрь 2007
Доступ к внутреннему типу или внутреннему члену сборки может осуществляться из другой сборки.
Заметки
Дружественные сборки позволяют осуществлять доступ к внутренним членам. Закрытые типы и закрытые члены останутся недоступными.
Чтобы предоставить сборке (сборка B) доступ к внутренним типам и членам другой сборки (сборка A), используйте атрибут InternalsVisibleToAttribute в сборке A.
Примечание. |
---|
При компиляции сборки (сборка 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#)