Дружественные сборки
Дружественная сборка — это сборка, которая может обращаться к внутренним (C#) или дружественным (Visual Basic) типам и членам другой сборки. Если добавить атрибут сборки в AssemblyA, чтобы определить AssemblyB как другую сборку, вам больше не нужно пометить типы и члены в AssemblyA как общедоступные, чтобы они были доступны AssemblyB. Это особенно удобно в следующих ситуациях:
Во время модульного теста, если тестовый код выполняется в отдельной сборке, но требует доступа к членам тестируемой сборки, помеченным как
internal
в C# илиFriend
в Visual Basic.При разработке библиотек классов, если дополнения к этой библиотеке содержатся в отдельных сборках, но требуют доступа к членам в существующих сборках, помеченным как
internal
в C# илиFriend
в Visual Basic.
Замечания
С помощью атрибута InternalsVisibleToAttribute можно определить одну или несколько дружественных сборок для указанной сборки. В следующем примере атрибут используется InternalsVisibleToAttribute в AssemblyA и указывается сборка AssemblyB в качестве дружественной сборки. В результате сборка AssemblyB получает доступ ко всем типам и членам в сборке Assembly A, помеченным как internal
в C# или Friend
в Visual Basic.
Примечание.
При компиляции сборки, такой как AssemblyB, которая будет получать доступ к внутренним типам или внутренним членам другой сборки, например AssemblyA, необходимо явно указать имя выходного файла (.exe или .dll) с помощью параметра компилятора -out. Это необходимо потому, что компилятор еще не создал имя сборки, формируемой во время привязки к внешним ссылкам. Дополнительные сведения см. в разделе OutputAssembly (C#) или -out (Visual Basic).
using System.Runtime.CompilerServices;
using System;
[assembly: InternalsVisibleTo("AssemblyB")]
// The class is internal by default.
class FriendClass
{
public void Test()
{
Console.WriteLine("Sample Class");
}
}
// Public class that has an internal method.
public class ClassWithFriendMethod
{
internal void Test()
{
Console.WriteLine("Sample Method");
}
}
Imports System.Runtime.CompilerServices
<Assembly: InternalsVisibleTo("AssemblyB")>
' Friend class.
Friend Class FriendClass
Public Sub Test()
Console.WriteLine("Sample Class")
End Sub
End Class
' Public class with a Friend method.
Public Class ClassWithFriendMethod
Friend Sub Test()
Console.WriteLine("Sample Method")
End Sub
End Class
Доступ к типам и членам internal
(C#) или Friend
(Visual Basic) могут получить только те сборки, которые будут явно обозначены как дружественные. Например, если сборка AssemblyB является дружественной для сборки Assembly A, а сборка Assembly C ссылается на сборку AssemblyB, сборка Assembly C не получает доступ к типам internal
(C#) или Friend
(Visual Basic) в сборке Assembly A.
Компилятор выполняет некоторые основные проверки имени дружественной сборки, передаваемого в атрибут InternalsVisibleToAttribute. Если сборка Assembly A объявляет AssemblyB как дружественную сборку, действуют следующие правила проверки:
Если сборка Assembly A имеет строгое имя, сборка AssemblyB должна также иметь строгое имя. Имя дружественной сборки, передаваемое в атрибут, должно состоять из имени сборки и открытого ключа из ключа строгого имени, который используется для подписи сборки AssemblyB.
Имя дружественной сборки, передаваемое в атрибут InternalsVisibleToAttribute, не может быть строгим именем сборки AssemblyB. Не следует включать версию сборки, язык и региональные параметры, архитектуру или маркер открытого ключа.
Если сборка Assembly A не имеет строгого имени, имя дружественной сборки должно состоять только из имени сборки. Дополнительные сведения см. в разделе "Практическое руководство . Создание неподписанных сборок друзей".
Если сборка AssemblyB имеет строгое имя, нужно указать ключ строгого имени для сборки AssemblyB, используя параметр проекта или параметр компилятора командной строки
/keyfile
. Дополнительные сведения см. в статье "Практическое руководство. Создание подписанных дружественных сборок".
Класс StrongNameIdentityPermission также позволяет обеспечить общий доступ к типам, но имеет следующие отличия:
Класс StrongNameIdentityPermission применяется к отдельному типу, тогда как дружественная сборка относится ко всей сборке.
Если в сборке Assembly A существуют сотни типов, которые должны использоваться совместно со сборкой AssemblyB, к каждому из них необходимо добавить StrongNameIdentityPermission. Если используется дружественная сборка, достаточно объявить дружественные отношения всего один раз.
Если вы используете StrongNameIdentityPermission, типы для общего доступа необходимо объявить как открытые. При использовании дружественной сборки общие типы объявляются как
internal
(C#) илиFriend
(Visual Basic).
Сведения о том, как получить доступ к типам и методам сборки internal
(C#) или Friend
(Visual Basic) из файла модуля (файлу с расширением .netmodule), см. в разделе ModuleAssemblyName (C#) или -moduleassemblyname (Visual Basic).