Литмир - Электронная Библиотека
A
A

3. В-третьих, расширяемое приложение должно получать ссылку на требуемую инфраструктуру (вроде набора интерфейсных типов) и вызывать члены для запуска лежащей в основе функциональности. Это может требовать позднего связывания.

Попросту говоря, если расширяемое приложение изначально запрограммировано для запрашивания специфических интерфейсов, то во время выполнения оно в состоянии выяснять, может ли быть активизирован интересующий тип. После успешного прохождения такой проверки тип может поддерживать дополнительные интерфейсы, которые формируют полиморфную фабрику его функциональности. Именно этот подход был принят командой разработчиков Visual Studio, и вопреки тому, что вы могли подумать, в нем нет ничего сложного!

Построение расширяемого приложения

В последующих разделах будет рассмотрен пример создания расширяемого приложения, которое может быть дополнено функциональностью внешних сборок. Расширяемое приложение образовано из следующих сборок.

CommonSnappableTypes.dll
. Эта сборка содержит определения типов, которые будут использоваться каждым объектом оснастки. На нее будет напрямую ссылаться расширяемое приложение.

CSharpSnapIn.dll
. Оснастка, написанная на С#, в которой задействованы типы из сборки
CommonSnappableTypes.dll
.

VBSnapIn.dll
. Оснастка, написанная на Visual Basic, в которой применяются типы из сборки
CommonSnappableTypes.dll
.

MyExtendableApp.ехе
. Консольное приложение, которое может быть расширено функциональностью каждой оснастки.

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

На заметку! Вы можете подумать о том, что вам вряд ли будет ставиться задача построения консольного приложения, и тут вы вероятно правы! Бизнес-приложения, создаваемые на языке С#, обычно относятся к категории интеллектуальных клиентов (Windows Forms или WPF), веб-приложений/служб REST (ASP.NET Core) или автоматических процессов (функций Azure, служб Windows и т.д.). Консольные приложения применяются здесь, чтобы сосредоточиться на специфических концепциях примеров, в данном случае — на динамической загрузке, рефлексии и позднем связывании. Позже в книге вы узнаете, как строить "реальные" пользовательские приложения с использованием WPF и ASP.NET Core.

Построение мультипроектного решения ExtendableApp

Большинство приложений, созданных ранее в книге, были автономными проектами с небольшими исключениями (вроде предыдущего приложения). Так делалось для того, чтобы сохранять примеры простыми и четко ориентированными на демонстрируемые в них аспекты. Однако в реальном процессе разработки обычно приходится работать с множеством проектов в одном решении.

Создание решения и проектов с помощью интерфейса командной строки

Открыв окно интерфейса CLI, введите следующие команды, чтобы создать новое решение, проекты для библиотек классов и консольного приложения, а также ссылки на проекты:

dotnet new sln -n Chapter17_ExtendableApp

dotnet new classlib -lang c# -n CommonSnappableTypes

  -o .\CommonSnappableTypes -f net5.0

dotnet sln .\Chapter17_ExtendableApp.sln add .\CommonSnappableTypes

dotnet new classlib -lang c# -n CSharpSnapIn -o .\CSharpSnapIn -f net5.0

dotnet sln .\Chapter17_ExtendableApp.sln add .\CSharpSnapIn

dotnet add CSharpSnapin reference CommonSnappableTypes

dotnet new classlib -lang vb -n VBSnapIn -o .\VBSnapIn -f net5.0

dotnet sln .\Chapter17_ExtendableApp.sln add .\VBSnapIn

dotnet add VBSnapIn reference CommonSnappableTypes

dotnet new console -lang c# -n MyExtendableApp -o .\MyExtendableApp -f net5.0

dotnet sln .\Chapter17_ExtendableApp.sln add .\MyExtendableApp

dotnet add MyExtendableApp reference CommonSnappableTypes

Добавление событий PostBuild в файлы проектов

При компиляции проекта (либо в Visual Studio, либо в командной строке) существуют события, к которым можно привязываться. Например, после каждой успешной компиляции нужно копировать две сборки оснасток в каталог проекта консольного приложения (в случае отладки посредством

dotnet run
) и в выходной каталог консольного приложения (при отладке в Visual Studio). Для этого будут использоваться несколько встроенных макросов.

Вставьте в файлы

CSharpSnapin.csproj
и
VBSnapIn.vbproj
приведенный ниже блок разметки, который копирует скомпилированную сборку в каталог проекта
MyExtendableApp
и в выходной каталог(
MyExtendableApp\bin\debug\net5.0
):

<Target Name="PostBuild" AfterTargets="PostBuildEvent">

    <Exec Command="copy $(TargetPath) $(SolutionDir)MyExtendableApp\

    $(OutDir)$(TargetFileNa
me)

    /Y 
copy $(TargetPath) $(SolutionDir)MyExtendableApp\

    $(TargetFileName) /Y" />

</Target>

Теперь после компиляции каждого проекта его сборка копируется также в целевой каталог приложения

MyExtendableApp
.

Создание решения и проектов с помощью Visual Studio

Вспомните, что по умолчанию среда Visual Studio назначает решению такое же имя, как у первого проекта, созданного в этом решении. Тем не менее, вы можете легко изменять имя решения.

Чтобы создать решение

ExtendableApp
, выберите в меню пункт FileNew Project (Файл►Создать проект). В открывшемся диалоговом окне Add New Project (Добавление нового проекта) выберите элемент Class Library (Библиотека классов) и введите
CommonSnappableTypes
в поле Project name (Имя проекта). Прежде чем щелкать на кнопке Create (Создать), введите
ExtendableApp
в поле Solution name (Имя решения), как показано на рис. 17.3.

Язык программирования C#9 и платформа .NET5 - _112.png

Чтобы добавить к решению еще один проект, щелкните правой кнопкой мыши на имени решения(

ExtendableApp
) в окне Solution Explorer и выберите в контекстном меню пункт AddNew Project (Добавить► Новый проект) или выберите в меню пункт FileAddNew Project (Файл►Добавить►Новый проект). При добавлении дополнительного проекта к существующему решению содержимое диалогового окна Add New Project слегка отличается; параметры решения теперь отсутствуют, так что вы увидите только информацию о проекте (имя и местоположение). Назначьте проекту библиотеки классов имя
CSharpSnapIn
и щелкните на кнопке Create.

333
{"b":"847442","o":1}