Главная » C# » Конфигурирование приложений и динамическая загрузка в Visual C# (Sharp)

0

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

Но методы, которые годятся для разработчика, не обязательно могут быть споучными для других. Возвратимся к примеру системы для контроля освещения, рассмотренному в главе 8. Там мы создали модуль ядра, который был ответствеым за включение и выключение освещения. Реализации отдельных комнат нахились в предопределенной сборке с конкретным именем. Такая архитектура была бы неработоспособной с применением библиотеки стороннего разработчика, т. к. ядро ожидает сборку с определенным именем. Возможно,  вы  думаете:  "Подумшь, проблема. Это проблему легко решить — нужно всего лишь удалить старую сборку и переименовать свою сборку на имя старой сборки". Такое решение было бы  рабочим,  но  в то же  самое  время оно создало бы  многочисленные трудности с администрированием программы. Правильным решением будет указать програе, чтобы для реализаций отдельных комнат она использовала определенную сбоу и определенные типы. Эта информация предоставляется программе в текстовом файле. Файл, который указывает программе на необходимость выполнения опреденной  задачи,  называется конфигурационным файлом  времени  исполнения.

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

Соглашение превыше конфигурации

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

На рисунке прямоугольники  представляет отдельные сборки, содержащие опредения интерфейсов, реализации и ядро. Целью всех этих сборок является предостить возможность обновления отдельной сборки, без необходимости обновлять их все. Но на рисунке не показано, что приложение должно иметь возможность обраться ко всем трем сборкам. Отсутствие одной из этих сборок будет проблемой, т. к. приложение не сможет работать.

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

Посмотрим на этот совет с точки зрения кода. Допустим, что следующее определие интерфейса находится в сборке, содержащей все определения интерфейсов:

public interface IMyInterface { }

Реализующий интерфейс класс определяется в сборке implementations:

class MyImplementation : IMylnterface { }

Если  какой-либо  класс  в  другой  сборке  хочет  использовать  функциональность

My implementation, то создается следующая фабрика:

public static Factory {

public static IMylnterface Instantiate() { return new MyImplementation();

}

}

Так как класс MyImplementation не объявлен public, ТО класс Factory требуется определить в реализациях сборки. Это подразумевает, что использующая функциальность сборка имеет ссылку на реализации.

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

Чтобы решить проблему, представленную в главе 8, где мы создали ядро системы управления  освещением,  но не знали заранее реализаций  модулей для отдельных комнат,  необходимо  выполнить развязку  компонентов  во  время  исполнения  прожения. Это можно было бы сделать с помощью конфигурации, позволяя конеому пользователю подключать (plug in) реализации для комнат, контролируемые ядром. Разработчики называют развязку времени исполнения подключаемой архектурой  (http://en.wikipedia.org/wiki/Plugin),  Вот  здесь  и  находит  применение комбинация конфигурированного и обычного кода. "Соглашение превыше конфи-

гурации" (convention over configuration’) является философией  инфраструктуры RoR (Ruby on Rails, инфраструктура, предназначенная для ускорения, упрощения и повышения эффективности разработки Web-приложений, написанная на языке программирования Ruby), означающей, что разработчики определяют только нтандартные части своих приложений.

Использование архитектуры конфигурирования для выполнения развязки

В  конфигурационном  сценарии  времени   исполнения   архитектура,   показанная на рис. 8.5, не меняется; в ней остаются определения, реализации, ядро и половательские сборки. Меняется способ создания ссылок на индивидуальные кооненты.

Для начала рассмотрим простую ситуацию. У вас есть вопрос, и вы знаете, кто мог бы на него ответить. Вы знаете, что у этого человека есть телефон, но вы не знаете номер этого телефона. По аналогии с данной ситуацией, в программировании роль телефона играет интерфейс реализации, а задачей — установление связи с реализией. Номер телефона можно узнать в телефонной книге, которая содержит имена людей, их адреса и телефонные номера. Имена и адреса легко запоминаются, но телефонные номера поддаются запоминанию несколько труднее. Поэтому телонный справочник предназначен для создания перекрестной ссылки между легко запоминаемой информацией и трудно запоминаемой. В программировании перрестная  ссылка  предоставляется  файлом  конфигурации,  который  ассоциирован с конкретным приложением .NET. Получив перекрестную ссылку на информацию, мы знаем местонахождение сборки и можем создать экземпляр типа, указываемого перекрестной ссылкой. Таким образом, файл конфигурации предоставляет нам иормацию о местонахождении и имени типа.

Использование стандартной архитектуры для развязки

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

Стандартная архитектура пытается упростить конфигурирование, учреждая легко запоминаемый шаблон обращения к типу. Возьмем, например, телефонный номер 1-800-BIG-CARS.  Хоть  1  и  800 — числа, их легко запомнить,  а слова BIG  CARS,

1 Понятие "соглашение превыше конфигурации" означает, что разработчик должен указывать только нестандартные аспекты приложения. Например, если в модели имеется класс Продажи, то соответсующая таблица в базе данных по умолчанию называется продажи. Только если разработчик откляется от этой конвенции,  например,  называя  таблицу  проданные_товары, то  ему  нужно  писать код касательно этих имен. — Пер .

кроме того, что они являются словами, которые, в общем, легко поддаются запинанию, здесь еще несут и определенную смысловую  нагрузку.  Употребление слов вместо цифр в телефонном номере возможно потому, что каждой цифре на панели набора телефонного номера соотнесены три или четыре буквы. Таким обром, числовой номер, соответствующий буквенному BIG-CARS, будет 244-2277.

Соглашения могут быть полезными, но только если вы их знаете. Например, если вы не сведущи в системе телефонных номеров, то будете ломать себе голову, как слова BIG CARS могут быть телефонным номером, который по идее должен выраться числами. Информация, которой у вас нет, — это соглашение о том, как буы преобразуются в номер.

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

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

Источник: Гросс  К. С# 2008:  Пер. с англ. — СПб.:  БХВ-Петербург, 2009. — 576 е.:  ил. — (Самоучитель)

По теме:

  • Комментарии