Пошаговое руководство. Внедрение данных о типах из управляемых сборок (C# и Visual Basic)
Если данные о типе внедряются из управляемой сборки со строгим именем, то для получения программы, не зависящей от версии управляемой библиотеки, можно связать типы, используя слабую связь. Т. е. программа сможет использовать типы из нескольких версий управляемой библиотеки без повторной компиляции для каждой версии.
Внедрение типа часто используется с COM-взаимодействием, например приложение, которое использует объекты автоматизации Microsoft Office. Внедрение данных о типе позволяет одному построению программы работать с различными версиями Microsoft Office, установленными на разных компьютерах. Внедрение данных о типе можно также использовать в решении, написанном полностью на управляемом языке.
Данные о типе можно встроить из сборки, которая имеет следующие характеристики.
Сборка предоставляет по крайней мере один открытый интерфейс.
Внедренные интерфейсы отмечены атрибутом ComImport и атрибутом Guid (и имеют уникальный GUID).
Сборка отмечена атрибутом ImportedFromTypeLib или атрибутом PrimaryInteropAssembly, и атрибутом уровня сборки Guid. (По умолчанию шаблоны проектов Visual Basic и Visual C# включают установленный на уровне сборки атрибут Guid).
После указания открытых интерфейсов, которые можно внедрить, можно создать классы среды выполнения, которые реализуют эти интерфейсы. Клиентская программа встраивает данные о типе в эти интерфейсы на этапе разработки с помощью ссылки на сборку, которая содержит открытые интерфейсы, и присвоения параметру свойства Embed Interop Types ссылки значения True. Это равнозначно созданию ссылки на сборку в компиляторе с интерфейсом командной строки с помощью параметра /link. Затем клиентская программа может загрузить экземпляры объектов среды выполнения, указанные в качестве этих интерфейсов. При создании новой версии сборки со строгим именем повторная компиляция клиентской программы с обновленной сборкой среды выполнения не требуется. Вместо этого клиентская программа будет использовать любую доступную версию сборки среды выполнения, используя внедренные данные о типе для открытых интерфейсов.
Поскольку основная функция внедрения типа — поддержка внедрения информации о типе из сборок с COM-взаимодействием, при внедрении информации о типе в полностью управляемое решение накладываются следующие ограничения.
Внедряются только атрибуты, специфичные для COM-взаимодействия; остальные атрибуты игнорируются.
Если тип использует универсальные параметры и тип универсального параметра является внедренным типом, этот тип не может использоваться через границы сборок. Примеры использования через границы сборок включают вызов метода из другой сборки или наследование типа от типа, определенного в другой сборке.
Контакты не могут быть внедрены.
Класс System.Collections.Generic.Dictionary<TKey, TValue> не поддерживает внедренный тип в качестве ключа. Для поддержки внедренного типа в качестве ключа следует реализовать собственный тип словаря.
В данном пошаговом руководстве выполняются следующие задачи.
Создание сборки со строгим именем, которая имеет открытый интерфейс, содержащий данные о типе, которые можно внедрить.
Создание сборки среды выполнения со строгим именем, которая реализует открытый интерфейс.
Создание клиентской программы, в которую внедрены данные о типе из открытого интерфейса и которая создает экземпляр класса из сборки среды выполнения.
Изменение и повторное построение сборки среды выполнения.
Запуск клиентской программы для проверки того, что используется новая версия сборки среды выполнения и отсутствует необходимость в повторной компиляции клиентской программы.
Примечание
На вашем компьютере названия некоторых элементов интерфейса пользователя Visual Studio или их расположение могут отличаться от указанных в нижеследующих инструкциях. Это зависит от имеющегося выпуска Visual Studio и используемых параметров. Дополнительные сведения см. в разделе Параметры Visual Studio.
Создание интерфейса
Создание проекта интерфейса с эквивалентностью типов
В Visual Studio в меню Файл последовательно выберите пункты Создать и Проект.
Убедитесь, что в диалоговом окне Новый проект в области Типы проектов выбран пункт Windows. В области Шаблоны выберите пункт Библиотека классов. В поле Имя введите TypeEquivalenceInterface и нажмите кнопку ОК. Новый проект создан.
В обозревателе решений щелкните правой кнопкой мыши файл Class1.vb или Class1.cs и выберите команду Переименовать. Переименуйте файл в ISampleInterface.vb или ISampleInterface.cs и нажмите клавишу ВВОД. При переименовании файла класс также будет переименован в ISampleInterface. Этот класс будет представлять открытый интерфейс для класса.
Щелкните правой кнопкой мыши проект TypeEquivalenceInterface и выберите пункт Свойства. Щелкните вкладку Компиляция в Visual Basic или вкладку Построение в Visual C#. В качестве пути к выходному файлу укажите допустимое расположение на компьютере разработчика, например C:\TypeEquivalenceSample. Указанное расположение также будет использоваться при выполнении дальнейших инструкций данного пошагового руководства.
Не выходя из свойств проекта, откройте вкладку Подписывание. Выберите пункт Подписать сборку. В списке Выберите файл ключей строгого имени выберите пункт <Создать...>. В поле Имя файла ключей введите key.snk. Снимите флажок Защитить мой файл ключей паролем. Нажмите кнопку ОК.
Откройте файл ISampleInterface.vb или ISampleInterface.cs. Чтобы создать интерфейс ISampleInterface, добавьте в файл класса ISampleInterface приведенный ниже код.
Imports System.Runtime.InteropServices <ComImport()> <Guid("8DA56996-A151-4136-B474-32784559F6DF")> Public Interface ISampleInterface Sub GetUserInput() ReadOnly Property UserInput As String ... End Interface
using System; using System.Runtime.InteropServices; namespace TypeEquivalenceInterface { [ComImport] [Guid("8DA56996-A151-4136-B474-32784559F6DF")] public interface ISampleInterface { void GetUserInput(); string UserInput { get; } ... } }
В меню Сервис выберите команду Создать Guid. В диалоговом окне Создать GUID выберите пункт Формат реестра и щелкните Копировать. Нажмите кнопку Выход.
В атрибуте Guid удалите пример GUID и вставьте GUID, который был скопирован из диалогового окна Создать GUID. Удалите фигурные скобки ({}) из скопированного GUID.
В Visual Basic в меню Проект выберите пункт Показать все файлы. Пропустите данный шаг, если используется Visual C#.
В обозревателе решений разверните папку Мой проект, если используется Visual Basic. Если используется Visual C#, разверните папку Свойства. Дважды щелкните файл AssemblyInfo.vb или AssemblyInfo.cs. Добавьте в файл следующий атрибут.
<Assembly: ImportedFromTypeLib("")>
[assembly: ImportedFromTypeLib("")]
Сохраните файл.
Сохраните проект.
Щелкните правой кнопкой мыши проект TypeEquivalenceInterface и выберите команду Построить. DLL-файл библиотеки классов будет скомпилирован и сохранен по пути, который указан для выходного файла (например, C:\TypeEquivalenceSample).
Создание класса среды выполнения
Создание проекта среды выполнения с эквивалентностью типов
В Visual Studio в меню Файл последовательно выберите пункты Создать и Проект.
Убедитесь, что в диалоговом окне Новый проект в области Типы проектов выбран пункт Windows. В области Шаблоны выберите пункт Библиотека классов. В текстовом поле Имя введите TypeEquivalenceRuntime и нажмите кнопку ОК. Новый проект создан.
В обозревателе решений щелкните правой кнопкой мыши файл Class1.vb или Class1.cs и выберите команду Переименовать. Переименуйте файл в SampleClass.vb или SampleClass.cs и нажмите клавишу ВВОД. При переименовании файла класс также будет переименован в SampleClass. Этот класс будет реализовывать интерфейс ISampleInterface.
Щелкните правой кнопкой мыши проект TypeEquivalenceRuntime и выберите пункт Свойства. Щелкните вкладку Компиляция в Visual Basic или вкладку Построение в Visual C#. В качестве пути к выходному файлу укажите то же расположение, которое использовалось в проекте TypeEquivalenceInterface, например C:\TypeEquivalenceSample.
Не выходя из свойств проекта, откройте вкладку Подписывание. Выберите пункт Подписать сборку. В списке Выберите файл ключей строгого имени выберите пункт <Создать...>. В поле Имя файла ключей введите key.snk. Снимите флажок Защитить мой файл ключей паролем. Нажмите кнопку ОК.
Щелкните правой кнопкой мыши проект TypeEquivalenceRuntime и в контекстном меню выберите команду Добавить ссылку. Щелкните вкладку Обзор и выберите папку, содержащую выходной файл. Выберите файл TypeEquivalenceInterface.dll и нажмите кнопку ОК.
В Visual Basic в меню Проект выберите пункт Показать все файлы. Пропустите данный шаг, если используется Visual C#.
В обозревателе решений разверните папку Ссылки. Выберите ссылку TypeEquivalenceInterface. В окне свойств ссылки TypeEquivalenceInterface для свойства Указанная версия задайте значение False.
Чтобы создать класс SampleClass, добавьте следующий код в файл класса SampleClass.
Imports TypeEquivalenceInterface Public Class SampleClass Implements ISampleInterface Private p_UserInput As String Public ReadOnly Property UserInput() As String Implements ISampleInterface.UserInput Get Return p_UserInput End Get End Property Public Sub GetUserInput() Implements ISampleInterface.GetUserInput Console.WriteLine("Please enter a value:") p_UserInput = Console.ReadLine() End Sub ... End Class
using System; using System.Collections.Generic; using System.Linq; using System.Text; using TypeEquivalenceInterface; namespace TypeEquivalenceRuntime { public class SampleClass : ISampleInterface { private string p_UserInput; public string UserInput { get { return p_UserInput; } } public void GetUserInput() { Console.WriteLine("Please enter a value:"); p_UserInput = Console.ReadLine(); } ... } }
Сохраните проект.
Щелкните правой кнопкой мыши проект TypeEquivalenceRuntime и выберите команду Построить. DLL-файл библиотеки классов будет скомпилирован и сохранен по пути, который указан для выходного файла (например, C:\TypeEquivalenceSample).
Создание клиентского проекта
Создание клиентского проекта с эквивалентностью типов
В Visual Studio в меню Файл последовательно выберите пункты Создать и Проект.
Убедитесь, что в диалоговом окне Новый проект в области Типы проектов выбран пункт Windows. В области Шаблоны выберите пункт Консольное приложение. В текстовом поле Имя введите TypeEquivalenceClient и нажмите кнопку ОК. Новый проект создан.
Щелкните правой кнопкой мыши проект TypeEquivalenceClient и выберите пункт Свойства. Щелкните вкладку Компиляция в Visual Basic или вкладку Построение в Visual C#. В качестве пути к выходному файлу укажите то же расположение, которое использовалось в проекте TypeEquivalenceInterface, например C:\TypeEquivalenceSample.
Щелкните правой кнопкой мыши проект TypeEquivalenceClient и в контекстном меню выберите команду Добавить ссылку. Щелкните вкладку Обзор и выберите папку, содержащую выходной файл. Выберите файл TypeEquivalenceInterface.dll (не файл TypeEquivalenceRuntime.dll) и нажмите кнопку ОК.
В Visual Basic в меню Проект выберите пункт Показать все файлы. Пропустите данный шаг, если используется Visual C#.
В обозревателе решений разверните папку Ссылки. Выберите ссылку TypeEquivalenceInterface. В окне свойств ссылки TypeEquivalenceInterface для свойства Embed Interop Types задайте значение False.
Чтобы создать клиентскую программу, добавьте в файл Module1.vb или Program.cs следующий код.
Imports TypeEquivalenceInterface Imports System.Reflection Module Module1 Sub Main() Dim sampleAssembly = Assembly.Load("TypeEquivalenceRuntime") Dim sampleClass As ISampleInterface = CType( _ sampleAssembly.CreateInstance("TypeEquivalenceRuntime.SampleClass"), ISampleInterface) sampleClass.GetUserInput() Console.WriteLine(sampleClass.UserInput) Console.WriteLine(sampleAssembly.GetName().Version) Console.ReadLine() End Sub End Module
using System; using System.Collections.Generic; using System.Linq; using System.Text; using TypeEquivalenceInterface; using System.Reflection; namespace TypeEquivalenceClient { class Program { static void Main(string[] args) { Assembly sampleAssembly = Assembly.Load("TypeEquivalenceRuntime"); ISampleInterface sampleClass = (ISampleInterface)sampleAssembly.CreateInstance("TypeEquivalenceRuntime.SampleClass"); sampleClass.GetUserInput(); Console.WriteLine(sampleClass.UserInput); Console.WriteLine(sampleAssembly.GetName().Version.ToString()); Console.ReadLine(); } } }
Чтобы построить и запустить программу, нажмите сочетание клавиш CTRL+F5.
Изменение интерфейса
Изменение интерфейса
В меню Visual Studio Файл выберите пункт Открыть и пункт Решение или проект.
В диалоговом окне Открыть проект щелкните правой кнопкой мыши проект TypeEquivalenceInterface и выберите пункт Свойства. Щелкните вкладку Приложение. Нажмите кнопку Сведения о сборке. В поле Версия сборки и Версия файла измените значения на 2.0.0.0.
Откройте файл ISampleInterface.vb или ISampleInterface.cs. Добавьте следующую строку кода в интерфейс ISampleInterface.
Function GetDate() As Date
DateTime GetDate();
Сохраните файл.
Сохраните проект.
Щелкните правой кнопкой мыши проект TypeEquivalenceInterface и выберите команду Построить. Новая версия DLL-файла библиотеки классов будет скомпилирована и сохранена по пути, который указан для выходного файла (например, C:\TypeEquivalenceSample).
Изменение класса среды выполнения
Изменение класса среды выполнения
В меню Visual Studio Файл выберите пункт Открыть и пункт Решение или проект.
В диалоговом окне Открыть проект щелкните правой кнопкой мыши проект TypeEquivalenceRuntime и выберите пункт Свойства. Щелкните вкладку Приложение. Нажмите кнопку Сведения о сборке. В поле Версия сборки и Версия файла измените значения на 2.0.0.0.
Откройте файл SampleClass.vb или SampleClass.cs. Добавьте следующие строки кода в класс SampleClass.
Public Function GetDate() As DateTime Implements ISampleInterface.GetDate Return Now End Function
public DateTime GetDate() { return DateTime.Now; }
Сохраните файл.
Сохраните проект.
Щелкните правой кнопкой мыши проект TypeEquivalenceRuntime и выберите команду Построить. Обновленная версия DLL-файла библиотеки классов будет скомпилирована и сохранена по пути, который указан для выходного файла (например, C:\TypeEquivalenceSample).
В проводнике откройте папку, содержащую выходной файл (например, C:\TypeEquivalenceSample). Чтобы запустить программу, дважды щелкните файл TypeEquivalenceClient.exe. Несмотря на то, что повторная компиляция не выполнена, в программе отображается новая версия сборки TypeEquivalenceRuntime.
См. также
Ссылки
/link (параметры компилятора C#)
Основные понятия
Руководство по программированию на C#