305 97 26MB
Russian Pages 244 Year 2002
Р У С С К А Я Р Е Ц А Ц У
Microsoft
Моей дочери Аннабел Роз Платт
David S. Platt
Producing MICROSOFT
.NET Microsoft Press
Дэвид С. Платт
Знакомство с MICROSOFT
.NET Москва 2001
( А И Е Щ К Ш
УДК 004 ББК 32.973.26-018.2 П45
П45
Платт Д. С. Знакомство с Microsoft .NET/Пер. с англ. — М.: Издательско-торговый дом «Русская Редакция», 2001. — 240 с.: ил. ISBN 5-7502-0186-4 Книга Дэвида Платта знакомит читателя с новейшей и многообещающей платформой — Microsoft .NET. В ней доступно описаны особенности архитектуры и компоненты этой системы. Вы узнаете, какие проблемы позволяет решить .NET, какие для этого используются подходы и как начать с ней работать. Книга содержит множество иллюстраций и примеров программ. Описанные здесь компоненты и технологии, такие как .NET Framework, ASP.NET, Web Forms, Web-службы и Windows Forms, позволят нам эффективно создавать программные продукты нового поколения для набирающей обороты платформы Microsoft .NET, Книга состоит из 5 глав и предметного указателя. УДК 004
ББК 32.973.26-018.2
Подготовлено к изданию по лицензионному договору с Microsoft Согэоration, Редмонд, Вашингтон, США. Macintosh — охраняемый товарный знак компании Apple Computer Inc. ActiveX, BackOffice, JScript, Microsoft, Microsoft Press, MSDN, NetShow, Outlook, PowerPoint, Visual Basic, Visual C++, Visual IntcrDev, Visual ]4 +, Visual SourceSafe, Visual Studio, Win32, Windows и Windows NT являются товарными знаками или охраняемыми товарными знаками корпорации Microsoft в США и/или других странах. Все другие товарные знаки являются собственностью соответствующих фирм. Все названия компаний, организаций и продуктов, а также имена лиц, используемые в примерах, вымышлены и не имеют никакого отношения к реальным компаниям, организациям, проауктам и лицам, © Оригинальное издание на английском языке, Дэвид С. Платт, 20Ш © ISBN 0-7356-1377-Х (англ) ISBN 5-7502-0186-4
Перевод на русский язык, Microsoft Corporation, 2007
© Оформление и подготовка к изданию. издательско-юрговыи дом '(Русская Редакция», 2001
Вступление Предисловие Глава 1 ВВЕДЕНИЕ В .NET Большой Интернет Поднимаем планку: общие проблемы инфраструктуры Планы, составленные наилучшим образом И все же, что это за .NET? Об этой книге Предостережение: ознакомительное ПО Песнь Интернету
Глава 2 ОБЪЕКТЫ .NET
IX XI 1 1 3 5 7 10 12 13
17
Суть проблемы 17 Архитектура решения 22 Вот так... И почем все это? 26 Простейший пример 27 Подробнее о пространствах имен .NET 34 Сборки 38 Понятие сборки 38 Сборки и развертывание 41 Сборки и управление версиями 46 Особенности объектно-ориентированного программирования ... 50 Наследование 51 Конструкторы объекта 57 Управление памятью в .NET 59 Взаимодействие с СОМ 68 Использование объектов СОМ из программ .NET 68 Использование объектов .NET из СОМ 74 Транзакции в .NET 76 Структурная обработка исключений 79 Безопасность доступа к коду 86
VI
Оглавление
Глава 3 ASP.NET
97
Суть проблемы Архитектура решения Простейший пример: создание простой страницы ASP.NET Еще кое-что об управляющих элементах Web Управление и настройка проектов Web-приложений: файл Web.config Управление состоянием в ASP.NET Безопасность в ASP Аутентификация Windows-аутентификация Cookie-аутентификация на основе форм Passport-аутентификация Авторизация Идентификационные данные Управление процессом
97 101 105 109 118 121 127 128 130 131 135 140 144 149
Глава 4 WEB-СЛУЖБЫ .NET
153
Суть проблемы Архитектура решения Простейший пример: создание Web-службы Самоописываемость Web-служб: WSDL-файлы Создание клиента Web-службы Случай 1: HTTP GET Случай 2: HTTP Post Случай 3: необработанный Soap Случай 4: синхронная работа интеллектуального SOAP-прокси Случай 5: асинхронная работа интеллектуального прокси SOAP Поддержка Web-служб в Visual Studio.NET Управление состоянием Web-службы
153 158 161 167 1 71 171 172 1 73 175 178 181 185
Оглавление
Глава 5 WINDOWS FORMS
VII
187
Суть проблемы 187 Архитектура решения 190 Простейший пример 192 Более сложный пример: события и элементы управления 195 Создание собственных элементов управления Windows Forms.. 199 Размещение элементов управления ActiveX в приложениях Windows Forms 204
Эпилог и благословение Предметный указатель Об авторе
209 211 219
Я познакомился с Дэвидом Платтом в 1998 г., когда обдумывал свою книгу о СОМ. Мой предполагаемый редактор также редактировал книгу Платта «COM and ActiveX Workbook» и дал мне ее экземпляр, чтобы я посмотрел, что публиковалось на эту тему раньше. Я нашел ее замечательной и очень подробной. (На самом деле тогда я в глаза не видел Дэйва, но ведь прочитать чьюто книгу — это все равно, что познакомиться с ее автором.) Прошло несколько лет (а я так и не выпустил ни одной книги о СОМ и DCOM по причине болезни), и я встретил Дэйва в своем офисе в Microsoft, на сей раз во плоти. К тому времени у меня была возможность прочитать его прекрасную книгу о СОМ + , чего и вам советую. Я ждал этой встречи! Мне хотелось узнать такой ли он веселый и интересный, как и его последняя книга. Он превзошел мои ожидания. Стиль Дэйва изменился со времен его ранних книг. В книге о СОМ+, как и в этой, много весьма непосредственных моментов и читать их очень весело. V него особый литературный стиль, хотя я и догадываюсь, что вы скажете: «Литературный стиль? Да ведь это компьютерные книги!» Знаете, я иной раз задумывался о классификации книг по программированию и выделил три их типа. • Основательные книги с большим объемом кода; в них обычно освещается одна конкретная тема. К этой категории относится книга Дэйва о СОМ и ActiveX. Такие книги отвечают на вопрос «как?» • Книги с очень глубоким анализом рассматриваемого предмета и небольшим объемом кода, например, книга Дона Бокса (Don Box) о технологии СОМ. Такие издания отвечают на вопрос «зачем?»
X
Вступление
• Книги-размышления. В них дается легкий для понимания об зор предмета и немного кода. При этом они не пытаются объяснить все и вся, как книги первой категории, и не погружают в предмет так глубоко, как книги второй. Их цель почти метафизическая: для понимания предмета вооружить вас подходом, подобным дзэн. Эти книги учат вас, когда задавать вопрос «как?», а когда — «зачем?» «Знакомство с Microsoft .NET» — безусловно, книга последнего типа. Ее очень приятно читать, она информативна и содержит много интересного кода. Она формирует отношение к .NET и, поверьте, делает это отлично. Чтобы стать специалистом no .NET вам потребуется изменить свой образ мышления. Но это не так уж сложно, и книга, которую вы держите в руках, — первый шаг в этом направлении. Кэйт Болинджер (Keith BalHnger) Менеджер программы .NET Framework Microsoft Corporation P.S. Меня всегда интересовало, что заставляет людей читать вступления. Если с вами это случилось, помогите мне в моих исследованиях, напишите мне по адресу [email protected]. О результатах сообщу.
Я всегда считал, что продукт, который сейчас называется Microsoft .NET, — это круто. Я помню статьи Мэри Киртлэнд (Магу Kirtland) в ноябрьском и декабрьском номерах Microsoft Systems journal за 1997 г. В них описывалось то, что тогда называлось COM4-, — среда периода выполнения, предоставляющая разные полезные возможности вроде межъязыкового наследования и контроля доступа в период выполнения. Мне, помешанному на СОМ, понравились способы, которыми эта среда обещала решить массу бесивших меня проблем СОМ. Затем в Microsoft решили, что следующая версия Microsoft Transaction Server будет называться COM4- 1.0 и будет интегрирована с Windows 2000, а то, о чем писала Мэри, будет СОМ+ 2.0. Позднее Microsoft переименовала COM4- в Microsoft .NET и для всей этой возни я выдумал новый термин — MINFU, Microsoft Nomenclature Foul-Up (Терминологическая Неразбериха Microsoft). Но звучит название продукта все же круто, и я был приятно удивлен, когда в Microsoft меня попросили написать о нем книгу, придерживаясь такого же общего подхода как для COM4- 1.0 в книге Understanding COM+ (Microsoft Press, 1999). Вот эту книгу вы сейчас и держите в руках (надеюсь, что вы ее купили). Я боялся, что Microsoft не позволит мне рассказать историю посвоему и заставит придерживаться линии партии. Но этого не произошло. Все, о чем я говорю в этой книге, — понравится вам это или нет — мое личное мнение. Конечно, мне нравится .NET, и я считаю, что она позволит обогатиться ее пользователям — Microsoft с этим не спорит. Когда предполагаемый работодатель просит у вас рекомендацию, чью рекомендацию вы дадите: того, кто считает вас полубогом или того, кто считает вас бараном? Большинство известных мне программистов дают немного тех и других. При обсуждении рукописи один менеджер, которому не понравились мои разглагольствования об административных средствах, написал мне: «По моему мнению, эта книга больше
XII
Предисловие
похожа на беллетристику, чем на руководство к действию. Это входило в ваши планы?» Я ответил: «Я горжусь, что моя книга указывает как на хорошие, так и плохие стороны .NET, как на плюсы, так и на минусы. Иначе я был бы льстецом. По моему скромному мнению, это и позволит ей стать руководством к действию. Если вы обвиняете меня в том, что я называю вещи своими именами, признаю себя виновным». Терпеть не могу скучного, сухого текста — как сухую рыбу или мясо. Помню, в колледже я попытался сдобрить отчет по лабораторной по химии шуточками и... завалился. «В науке не место легкомыслию, — изрек мой профессор — переделайте все заново. Используйте страдательный залог». V этого парня даже усы были будто нахмурены. Ты что, с наследством пролетел, Филипп? Расслабься — будешь жить дольше или хотя бы веселей! Может, он думал, что если будет скучным, то проживет дольше, но это ему не удастся. По-моему, лучшие авторы — это хорошие рассказчики, даже в таких и особенно в таких областях, как наука или история. Например, я восхищен «Нашествием чумы» Лори Гарре (Laurie Carrett, The Coming Plague, Penguin, 1995), «Сыном Венеры» Ивэна Коннела (Evan S. Connell, Son of the Morning Star, North Point Press, 1997) u биографией Уинстона Черчиля «Последний лев», которую написал Уильям Манчестер (William Manchester, The Last Lion, Little Brown, 1983). Вспомните свои учебники, написанные людьми вроде моего бывшего профессора. Что может быть гаже? А теперь прочитайте эту выдержку о поисках Эмилем Ру антитоксина от дифтерии и первых опытах на человеке во время эпидемии в Париже в 1894 г.: Ру глянул на беспомощных врачей, а затем перевел взгляд на свинцово-серые лица, руки, в страхе сжимающие края одеял, тела, извивающиеся в поисках глотка воздуха... Ру посмотрел на свой шприц — спасет ли эта сыворотка жизнь? «Да!» — воскликнул Эмиль Ру-человек. «Не знаю, нужен эксперимент», — прошептал Эмиль Ру — искатель истины.
Предисловие
XIII
«Но для эксперимента нам придется отказать в сыворотке минимум половине этих детей — мы не можем этого сделать». Так сказал Эмиль Ру — человек с большим сердцем — и голоса всех отчаявшихся родителей слились с молящим голосом этого Эмиля Ру. О том, какой выбор предпочел Эмиль Ру и к чему это привело, вы можете узнать из книги Поля де Крюифа «Охотники за микробами» (Paul de Kruif, Microbe Hunters), вышедшую в 1926 г. и периодически переиздающуюся (последний раз в 1996 г. в издательстве Harcourt Brace], В ней не так много академической точности, но что бы вы предпочли читать? Я знаю, что я предпочел бы писать. Я не претендую на красноречие де Крюифа и всерьез сомневаюсь, что кто-нибудь переиздаст эту книгу, пока мне не стукнет 112 лет. Но я сделал все, что мог, чтобы вы получили удовольствие, а кто из технических авторов хотя бы попытался это сделать? Книга Поля де Крюифа заканчивается так: «Эта не приукрашенная история была бы не полной, если бы я не сделал признания: я люблю этих охотников за микробами, от старика Антония Левенгука до Пауля Эрлиха. Не за их открытия и благодеяния для рода человеческого. Нет. Я люблю их за то, какие они люди. Не были, а есть — в моей памяти каждый из них жив и будет жить, пока мне служит мой мозг». Как говорится в моем эпилоге (не надо сразу к нему переходить, прочитайте сначала книгу), Интернет заставляет эволюционировать человеческий вид — ни больше, ни меньше. Microsoft .NET — это продукт, который обещает широко распахнуть мир Интернета. И для меня очень много значит, что я могу рассказать о нем и рассказать no-сзоему. Причина моего переключения на Microsoft Press и ухода от прежнего издателя — возможность работать над проектом с командой и обсуждать будущее технологий. Первые читатели рукописей сказали мне, что смогли пробиться через мой текст. В общем, я на это и надеялся. Каждая книга — дело коллективное, как полет на Луну, но в меньшем масштабе. Все лавры достаются автору, как и астронавтам (.будете следить, как мои акции идут вверх?), но без всех остальных людей, много работавших над этим проектом, и читать было
XIV
Предисловие
бы нечего. Благодарностей им достается немного, как и тысячам участников программы «Аполлон» (хотя я думаю, что в фильме «Аполлон 13» облаченный в жилет заядлый курильщик контролер полетов Джин Кранц в исполнении Эда Харриса переплюнул Джима Довела в исполнении Тома Хэнкса). Пока «Знакомство с Microsoft .NET» не экранизируют (кстати, прекрасная идея, надеюсь, меня слышит кто-нибудь из продюсеров) придется им за свои подвиги довольствоваться этими скромными благодарностями. Первая премия — Джону Пиэсу (John Pierce), главному редактору этой книги. Много лет назад, в моей книге Understanding СОМ+, изданной Microsoft Press, он играл роль второго плана. Я очень рад, что в этой книге он сыграл главную роль. У нас с ним одинаково извращенное чувство юмора. Подписать его на то, чтобы он держал меня в рамках, — все равно, что пригласить Билла Клинтона присматривать за старшеклассницами из группы поддержки спортивной команды. Я знал, что он не будет корежить мой стиль и ломать мой голос, который — нравится вам это или нет — отличается от остальных. Он отточил мою прозу так, как не смог бы сделать я сам. Дальше идет Марк Янг (Marc Young), технический редактор. Он находил ответы на все мои технические вопросы, обычно в условиях дефицита времени и ежедневных изменений в коде. Кроме Марка, многие другие члены команды разработки .NET находили окна в своем зверском графике, чтобы направить меня в нужном направлении. Я особенно признателен Сьюзан Уоррен (Susan Warren), Кэйту Болинджеру (Keith Ballinger), Марку Боултеру (Mark Boulter), Лорен Конфелдер (Loren Kohnfelder), Эрику Олсону (Erik Olson), Джону Риварду (John Rivard), Полу Вику (Paul Vick), Джеффри Рихтеру Geffrey Richter) и Саре Уильяме (Sara Williams). С коммерческой стороны процесс был запущен год назад Бэном Райаном (Ben Ryan), а после его ухода подхвачен Даниэлем Бердом (Danielle Bird). Поддержку осуществляла Энни Гамильтон (Anne Hamilton). Тереза Фэган (Teresa Fagan), менеджер продуктов в Microsoft Press, услышав название «Знакомство с Microsoft .NET» подала идею; «Эй, ты должен зарегистрировать это как Web-адрес!» — и я помчался под дождем в свою одинокую писа-
Предисловие
XV
тельскую мансарду (это был этаж для консьержек в отеле Club Hotel в Бельвью) и реализовал эту идею, пока никто другой до нее не додумался. Это была вишенка в водочке с мороженым. Я также признателен Дюан Бэйкер {Duane Baker) и Крису Бэллу (Chris Bell) из Interland, Inc. за совместную работу по установке Web-сайта, где вы можете увидеть демонстрационные программы к этой книге. И, наконец, я должен поблагодарить мою жену Линду, теперь мать моей дочери Эннабел. Дэвид С. Платт www. rollth un der. com Ипсвич, Массачусетс, США апрель 2001 г.
Г л а в а 1
Введение в Я нынче ночью не засну — болят года во мне. На вахте время потяну— с Тобой наедине. Опять сойду в машинный мрак: пойду к моей машине, : В морях поднявшей кавардак в трехмесячной путине. Р. Киплинг о важности доступа к системе 24 часа в сутки, 7 дней 8 неделю. («Молитва МакЭндрю», 1 894 г.)
Большой Интернет Интернет большой. (Раздраженный Читатель: «Я заплатил за то, чтобы знать НАСКОЛЬКО большой!». Подсчитывающий Гонорар Автор: «Я что-то не так сказал?») Сами по себе настольные ПК неинтересны. с ,/ Автономные ПК горазао как неинтересна и одноклеточная амеба. Ко- мемее лолезнЫ; че£ ПК, нечно, их можно использовать (ПК, а не соединенные в сеть, амеб), чтобы сыграть в главную игру — Пасьянс—-и компьютер не даст вам сжульничать (это достоинство?). Да и Блокнот всегда под рукой. Но в отличие от значения амебы в процессе эволюции, экономическое значение автономного ПК для общества не имеет мало-мальски достойного обоснования. Он просто не может делать многих полезных и интересных вещей, пока его кругозор ограничен его собственным ящиком. Однако когда вы через Интернет подключаете свой ПК ко всем
Здесь и далее стихотворения Р, Киплинга в переводе В. Топорова.
2
Глава 1
другим ПК з мире (и не только к ПК, но и другим интеллектуальным устройствам типа компьютеров на ладони или холодильников) — практически без затрат на дополнительную аппаратуру — начинают происходить забавные вещи. Одноклеточное эволюционирует и превращается в человекоподобное существо, способное сочинять, исполнять и ценить симфонии, взять вас с собой на Луну или уничтожать себе подобных. И на кой вам после этого Пасьянс? ;
Web начиналась как средство просмотра Интернет продолжает менять общество все скучных научных отчетов, но это давно поза: возрастающими 9 й - Она колоссально упростила распростратемпами. 1 нение всех видов данных. Растущие возможности представления данных привлекали к Интернету все новых пользователей, а рост аудитории подталкивал к активным действиям провайдеров контента, и этот замкнутый процесс продолжает набирать обороты, даже когда я пишу эти строки. Вчера я просматривал в Web голевые моменты из хоккейного матча, который я пропустил. Потом с помощью Napster нашел несколько приятных мелодий из 500 000 песен, записанных на жестких дисках 10 000 различных пользователей (меня, конечно, интересовали только легальные копии). Затем я рассказал маме, как нужно настроиться на соединение с моей видеокамерой, чтобы она посмотрела на свою внучку, спящую в колыбельке за 500 миль от нее. Интернет открывает нам особый мир, о котором мы не могли подумать даже пять лет назад. | Аппаратура для подключения к Интернету и каналы передачи данных постоянно дешевеют - Web-камера, позволяющая моей маме смотреть на внучку, стоит всего несколько сотен долларов и не требует никаких дополнительных расходов при работе через установленный у меня кабельный модем. Прикиньте, сколько бы это стоило десять или даже пять лет назад: купить видеоаппаратуру и оплатить выделенный канал от Ипсвича, штат Массачусетс, до Орвигсбурга, штат Пенсильвания. Цены на аппаратуру и услуги Интернета скоро упадут до уровня лотерейных выигрышей, если еще не упали,
Аппаратура и услуги доступа в Интернет дешевы и продолжают дешеветь,
Введение
3
Поднимаем планку: общие проблемы инфраструктуры Аппаратура и услуги Интернета дешевы, но Программы для есть одна загвоздка. Согласно Второму Зако- Интернета создают ну Платта, общее количество всякого рода новь*е классы проблем, неприятностей во Вселенной — величина |; требующие сложных 2 постоянная. Если кому-то приходится иметь дело с меньшим количеством неприятностей, то не потому, что они исчезли, а потому, что он свалил их на чужую голову. Если аппаратура и каналы связи легче и дешевле, значит, по вселенскому закону программы для Интернета на столько же сложнее и дороже. Это бесспорно, и каждый может в этом убедиться. Проблемы Интернет-приложений не связаны с бизнеслогикой, которая не отличается от таковой в настольных приложениях (если некоторое число меньше 0 — расходы по вашему счету превышены). Между тем тот факт, что приложение должно работать на нескольких машинах, связанных Интернетом, порождает новый класс проблем, которые определяются открытой, неконтролируемой и разнородной природой Интернета. Подумайте, как просто (относительно) уследить за малышом в собственной гостиной и насколько труднее это сделать на вокзале, Тот же ребенок, те же цели (безопасность, развлечения) и совершенно другое окружение. Рассмотрим, например, вопрос безопасносБеэопасностъ в настольти. Многие пользователи держат личную фи- ИЫХ приложениях нансовую информацию на автономном ПК и обычно вообще обрабатывают ее с помощью Quicken или =; не реализована, других подобных продуктов. Разработчики ранних версий Quicken не написали вообще никакого кода, обеспечивающего безопасность. Они были спокойны, точнее спокойны были их потребители, уверенные, что коль ПК физически недоступен, то никто их денежки не стянет. Параноики могли ку-
Первыи Закон Платта называется «Экспоненциальный рост оценочных значений» и утверждает, что каждый проект по разработке ПО требует атрое больше времени, чем при самых пессимистических оценках, даже если принимается во внимание сам этот закон.
4
Глава 1
пить продукты, защищающие всю систему с помощью паролей, но вряд ли многие это делали. Однако, узнавая о различных новшествах, многие пользователи стали понимать, что толку от Quicken на автономном компьютере не так уж много. Он мало чем отличался от бумажного реестра платежных документов, разве что работать можно было быстрей и проще. Quicken не давал никаких преимуществ сетевым пользователям, пока не предоставил возможность подключаться к Интернету и взаимодействовать с другими участниками финансовых операций для таких действий, как получение и оплата счетов и автоматическое получение выписок по банковским счетам и кредитным картам. (То есть Quicken дал бы эти преимущества сетевым пользователям, если бы не его кривой пользовательский интерфейс. По-настоящему он не справлялся с этими новыми возможностями, загружая пользователя бесконечным числом разных параметров, которые нужно было выбирать, Но это не проблема Интернета.) Но как только операции Quicken вышли за Итернет-приложения должны иметь средства пределы безопасного кокона — одного ПК, 'защиты на всех фазах на котором они выполнялись, — нужно было работы. призадуматься о защите. Например, когда пользователь просит электронный центр оплаты счетов выписать чек телефонной компании, центру нужно быть уверенным, что запрос пришел от истинного владельца счета, а не от телефонной компании, отчаянно пытающейся избежать банкротства путем перечисления самой себе авансовых платежей за много месяцев вперед. Кроме того, пересылаемые данные нужно шифровать. Вряд ли вы захотите, чтобы соседский сынокпридурок узнал номер вашего банковского счета, подключив к линии вашего кабельного модема сетевой анализатор пакетов (что скажет ваша жена, увидев счет на 295 долларов за услуги сауны «Веселые девчонки»?). Код, обеспечивающий безопасность, исключительно сложно писать (и проверять, и отлаживать, и разворачивать, и поддерживать, и сопровождать), когда сотрудники приходят и уходят. Вам нужно найти людей, знающих о безопасности все: как ауте н тиф и ц кровать пользователей, как решать, имеет ли
Созоавать безопасный код исключительно сложно.
Введение
5
пользователь право делать то или это, как шифровать данные, чтобы их могли легко прочитать авторизованные пользователи, но не могли злоумышленники, как создать средства, позволяющие администраторам устанавливать и удалять права пользователей и т. д. Интернет-вычисления порождают другие Безопасность и связансходные классы проблем, которые я рассмот- ные с ней проблемы рю далее в этой главе. Как л объяснил в сво- распределенных вычисей книге Understanding COM + (Microsoft лен ий-неотъемлемая Press, 1999), все эти проблемы сходны в том, принадле инфраструктуры. что они напрямую не связаны с бизнес-процессами, хотя именно за реализацию последних вам и платят деньги клиенты. Эти проблемы относятся к инфраструктуре, — как, например, к автотрассам или электрической сети —• к базе, на которой основана ваша повседневная жизнь. Реализация инфраструктуры убивает проек,-. ,- Инфраструктура, ты, Проекта, погибшего из-за бизнес-логики, ,, небшнес-логика я не видал. Вы знаете свои бизнес-процессы губит проекты, лучше всех, именно поэтому вы и пишете ПО, облегчающее управление ими. А инфраструктура вам неизвестна (если, конечно, не вы сами ее разрабатывали, как в случае с Microsoft). Экспертов по алгоритмам аутентификации и шифрования почти нет. Если вы попытаетесь сами написать такой код, произойдет одно из двух. Или ваша реализация будет увечной, потому что вы не понимаете, что делаете (вы легко отделаетесь, если о ней не узнают какие-нибудь нехорошие ребята), или вы не сможете довести дело до конца в рамках существующего бюджета. Когда я работал над распределенным приложением для торговли валютой (это было до Интернета, 12 лет назад; об этом тоже в моей книге Understanding COM + ), мы получили оба этих удовольствия.
Планы, составленные наилучшим образом Разработчики ПО всегда начинают проект с величественных замыслов и колоссальных обещаний. Как алкаш, стоящий у руля партии,
разработчики ПО сами себя обманывают,
6
Глава 1
мы клянемся, что благодаря тщательному проектированию мы избежим ошибок, а наш код весь будет полностью документирован. Мы его всесторонне оттестируем, а после этого никаких дополнительных функций включать не будем. Более того, мы составим реалистичный график и будем его придерживаться. («Эта функция ОС делает не совсем то, что нам нужно, но я за недельку напишу получше, так что наши требования к программе менять не надо».} Создать надежное и полезное (в меру) приложение — в наших силах; все, что нам нужно, — дисциплина. Никаких пасьянсов. Во всяком случае до пяти часов. Ну, ладно, одну игру во время обеда. «Черт! Проиграл! Еще разок для ровного счета, идет? Ого! Уже 16:00?» Все проекты, которые я знал, начинались с таким угарным пылом. Хоть кто-нибудь это сделал? Хоть один разработчик сдержал свои обещания? Нет. Такого никогда не было и не будет. Когда мы даем такие обещания, в глубине души мы знаем, что безбожно врем. Это не лечится. Как у наркоманов, выход здесь один (не считая летального исхода). Чтобы создавать успешные Интернетприложения мы должны вести себя смиренно, как выздоравливающие пациенты, и на пути нашем к праведности мы должны: 1. признаться себе в собственном бессилии — наша жизнь стала неуправляемой; 2. уверовать, что здравый рассудок вернет нам только сила, большая, чем наша. Прикладные программисты должны осозна изменить инфраструктуру Интерне' та мы бессильны. Это сделает наши проекты неуправляемыми. Мы не сможем их реализовать, они будут длиться слишком долго, стоить слишком много —мы не знаем сколько. Не стоит и пытаться — это самообман и верный путь к краху. В совершенно невероятном случае, если мы даже напишем пристойный код, наши конкуренты не заставят себя ждать и слопают наши завтраки, обеды и ужины тоже. Вы не строите собственное шоссе, чтобы водить свою машину и не устанавливаете собственный электрогенератор (если не живете в Калифорнии в начале 2001 г.)
Сами- построить инфраструктуру вы : не в состоянии'. :
вать что :
Введение
7
К счастью, требования вашего Интернет-приложения к инфраструктуре совпадают с требованиями всех остальных, так же как ваши требования к автострадам и электричеству такие же, как у других людей. На основании такой глобальной потребности правительство строит автомагистрали, а энергетические компании—электростанции, которыми вы пользуетесь за соответствующую плату (или непосредственно — оплачивая счета, или косвенно платя налоги). Правительство и коммунальные службы связаны с экономикой другого масштаба — для достижения своих целей они могут нанять или подготовить самых талантливых людей и амортизировать свои затраты из огромного числа источников, которые вам и не снились. Что нам на самом деле нужно, это чтобы кто- Нужно использовать то сделал для распределенных вычислений то инфраструктуру, же, что правительство делает для автомаги- а не строить ее. • стралей (может не буквально то, что делает правительство в этом направлении, но суть вы уловили). Как выздоравливающий наркоман верит, что вернуть его к жизни может только Сила, сотворившая Вселенную, так и разработчикам нужна высшая сила в области компьютеризации, обеспечивающая инфраструктуру Интернета и возвращающая здравый смысл разработчикам.
И все же, что это за .NET? Это и есть Microsoft .NET — готовая инфра- Microsoft NET структура для решения общих проблем Ин- предоставляет готовую тернет-приложений. Последнее время Micro- инфраструктуру для soft .NET невероятно много — даже для на- решения общих задач шей отрасли — рекламируется. Именно пог ппп 9^ Интернета, этому 5 000 чумовых фанатов, припухших от 1 Jolt Cola , собрались в Орландо, штат Флорида, в июле 2000 г. Не потому, что они не могут отказаться от покупки уцененных
Ходят слухи, что в качестве части приговора, вынесенного судьей Пенфилдом Джексоном, Microsoft впредь обязана подавать на своих конференциях только диетическую Jolt Cola, не содержащую кофеина. (Jolt Cola — напиток с повышенным содержанием сахара и кофеина. — Прим. перев.}
8
Глава 1
авиабилетов (даже если они не туда, куда им надо, да и вообще — не сезон) и не потому, что тащатся от жуткой жарь: и солнечных ударов. Они хотели первыми услышать о Microsoft .NET. Microsoft .NET — это прикомпоновываемая среда периода выполнения, работающая в ОС Windows 2000. Наверное, в будущем Министерство юстиции США постановит, чтобы она была частью ОС. Последующие версии могут предлагать часть своих возможностей для других версий Windows, а, вероятно, как мы увидим, и для других ОС. Сервис, обеспечиваемый .NET мы и обсудим далее в этой книге. • .NET Framework — среда периода выполнения, облегчающая написание полноценного надежного кода в сжатые сроки, управление, развертывание и модификацию .NET предоставляет этого к а новую среду периода °9 ' Написанные вами программы и выполнение ~- .NET компоненты выполняются в этой среде. Она Framework. дает программистам в период выполнения такие классные возможности, как автоматическое управление памятью (сборка мусора) и упрощенный доступ ко всем службам ОС. Она добавляет массу вспомогательных функций вроде простого доступа к Интернету и базам данных. Кроме того, она обеспечивает новый механизм повторного применения кода — более простой в использовании и в то же время более мощный и гибкий, чем СОМ. Развертывать .NET Framework проще, так как она не требует настройки реестра. Она также поддерживает на системном уровне стандартизированный механизм управления версиями. Все это доступно программистам на любом .NET-совместимом языке. .NET Framework мы обсудим в главе 2. • Хотя число специализированных программ растет, в ближайшей и среднесрочной перспективе для доступа к Интернету в качестве клиентского интерфейса мы будем .NET туреооставлйет новую программную использовать обычные браузеры, Для этого модель для создания серверам нужно создавать страницы с помоНТМ1-стра»иц — щью языка HTML, которые браузеры могут ASRNET. понимать и выводить пользователю. ASP.NET (следующая версия Active Server Pages) — это
Введение
9
новая среда, работающая на Internet Information Server (IIS), заметно упрощающая написание кода для создания HTMLстраниц. ASP.NET предлагает новый, не зависимый от языка способ создания кода и привязки его к запросам Web-страниц, — .NET Web Forms — управляемую событиями программную модель взаимодействия с элементами управления. Она делает программирование Web-страниц аналогичным программированию форм Visual Basic. ASP.NET содержит развитые средства управления сеансами и функции защиты. Она надежнее, и производительность ее значительно выше в сравнении с ASP. Про ASP.NET я расскажу в главе 3. • Хотя стандартные браузеры продолжают играть важную роль, я думаю, что буду- ,N£T предлагает cftoeoo обслуживания ш,ее за специализированными приложени- любых клиедаов ями и устройствами. Из Web можно будет Интернет-серверами не просто получить информацию и ото- .NET Web Services. бразить ее в браузере. Специализированный клиент (скажем, Napster для поиска музыки) будет через Интернет вызывать функции сервера и получать данные для отображения через специализированный пользовательский интерфейс, а в случае межмашинного взаимодействия пользовательский интерфейс вообще не потребуется. Microsoft .NET предлагает новый набор служб, позволяющих серверу предоставлять свои функции любому клиенту на любой машине с любой ОС. Клиент запрашивает сервер, применяя минимальный общий знаменатель — XML и HTTP. Набор предоставляемых таким образом функций называется Web-служба .NET. Вместо того чтобы сидеть и ждать, когда потребителей озарит и они падут в объятия Единственно Достойной Операционной Системы (аллилуйя!), надо просто сказать: «Покупайте нашу ОС, потому что мы предоставляем множество готовых функций, облегчающих написание приложений, способных взаимодействовать с любыми другими приложениями по всему миру, независимо от того, что они делают и где работают.» Я расскажу о Web-службах .NET в главе 4. • Специализированные пользовательские приложения, обращающиеся к Web-службам, нуждаются в хорошем пользователь-
1 0 NET предоставляет : 1 .Wmdows Forms — новый спосоё разработки i; шикарных клиентских • приложений с истюльзо- Г Framework.
Глава 1 ском
интерфейсе. Высококачественный интерфейс гораздо удобней, как, скажем, специализированный интерфейс Microsoft Outlook лучше универсального Web-интерфейса Hotmail. Microsoft .NET предоставляет новый Wjndows Forms/ _ облегчаю.
щий написание специализированных клиентских приложений с помощью .NET Framework. Чтобы представить себе его возможности, вообразите Visual Basic, сидящий на анаболических стероидах. .NET Windows Forms мы обсудим в главе 5. • Ни одна среда программирования для Интернета не будет полной без средств доступа к базам данных. Большинство Интенет-программ, по крайней мере сейчас, ADO- NET обеспечивает прекрасную поддержку расходуют львиную долю своего времени на доступа к базач* данных сбор информации от клиента, выполнение в рамках ,NET запросов к БД и представление результатов Framework. ; клиенту. .NET обеспечивает развитую поддержку работы с БД с помощью ADO. NET. Хотя здесь я эту технологию не обсуждаю, главу про ADO. NET можно загрузить с web-сайта этой книги www.introdudngmicrosoft.net,
Об этой книге Пока я не написал Understanding COM +, все мои книги были подробными руководствами с примерами на C++. Это очень нравилось продвинутым программистам на C+ + , но покупателей, увы, находилось немного, что очень удручало моих кредиторов. Я решил сделать эту книгу доступной для разработчиков, которые не знают или не любят С + + . Больше того, я обнаружил, что менеджеры абсолютно ничего не получают от моего С+ + -подхода, поскольку никогда не работают с примерами программ (было одно исключение — этому человеку я бесплатно отослал экземпляр своей книги, чтобы он трудился и над последующими). Я хочу расширить аудиторию и не ограничивать ее программистами. Безграмотные (или еще хуже — полуграмотные) менеджеры — твари исключительно опасные. Истребление этого вида было бы моим величайшим вкладом в развитие цивилизации.
Введение
11
В этой книге применяется стиль, с которым я г,„ Примеры программ экспериментировал в моем последнем опусе, днстручсими *ю их и приспособив формат, успешно использован- установке находятся на ный Давидом Чеппелом (David Chappel) в его web-саОте этой кнши. Understanding ActiveX and OLE (Microsoft Press, 1996 — Технологии ActiveX и OLE. M.: «Русская Редакция», 1997): множество пояснений и диаграмм и совсем немного кода в тексте. Как бы мне ни нравилась книга Дэвида Чаппела, кода мне все равно не хватало (как зачастую мне нужен кусочек шоколадного торта после изысканного суши). Я ловил себя на том, что пишу код, чтобы лучше понять его идеи, как писал уравнения для понимания текста в книге Стифена Хокинга (Stephen Hawking) «Краткая история времени». (Ладно, допустим, я — чокнутый.) Итак, для всех глав есть примеры программ, кое-что я написал сам, а кое-что — на основе примеров Microsoft. Эти примеры находятся на web-сайте книги, адрес которого, естественно, http://www.introdudngmicrosoft.net. Менеджеры и проектировщики могут читать эту книгу не захлебываясь кодом, а изголодавшиеся по коду программисты по-прежнему могут удовлетворить свой аппетит. Несмотря на весь шум вокруг С# (произносится «Си-шарп»), я написал код примеров на Visual Basic.NET,, поскольку с этим языком знакомо большинство читателей. Если вы захотите запустить примеры программ, вам потребуется компьютер с Windows 2000 Server, как минимум бета-версия Microsoft .NET SDK и предварительная версия Visual Studio.NET. Подробно требования к системе и настройке описаны на web-сайте. В каждой главе представлена одна последоВ каждой главе •.. вательно рассматриваемая тема. Я начинаю представлена оана тема с описания архитектурных проблем, подлежа- в нисходящем порядке. ш,их разрешению. Затем объясняю архитектуру верхнего уровня той инфраструктуры, которую .NET предоставляет, чтобы решить проблему, кодируя как можно меньше. После этого я перехожу к простейшему примеру решения проблемы. Менеджеры могут прекратить чтение после этого раздела. Затем идет обсуждение всяких тонких моментов: альтернативных вариантов, граничных условий и т. п. Я всюду пытаюсь следовать закону Порнелля, придуманного Джерри Порнеллем (Jerry Pournelle) в его рубрике «Владения хаоса» в журнале Byte, который формулируется очень просто: слишком много примеров не бывает.
t2
Глава 1
Предостережение: ознакомительное ПО Современное ПО — наиболее быстро меняющаяся область человеческой деятельности, из всех когда-либо существовавших. При написании книги об актуальном ПО требуется компромисс между точностью и своевременностью. Если вы начнете писать, когда ПО действительно начнет поставляться, книга окажется на полках через полгода или через год после выхода ПО. А это может составлять половину жизненного срока программы, а то и больше. С другой стороны, если вы приступите к книгу слишком рано, в процессе разработки, окончательная версия ПО слегка утратит сходство с тем, что описано в книге. Я всегда старался откладывать написание функциональной спецификации продукта до момента его поставки — это единственный способ гарантировать соответствие продукта спецификации.
Выбрать момент аля написания книги по программированию довольно сложно.
Я написал эту книгу в первом квартале 2001 г., используя версию Beta 2 Microsoft .NET Framework u Visual Studio.NET. Я даю абсолютную гарантию, что некоторые функции в период между написанием этой книги и выходом окончательной версии ПО будут изменены: могут быть добавлены новые, ожидаемые удалены, а существующие изменены. Я ведь тоже, когда планирую направление разработки собственного проекта по мере его приближения к завершению или когда хочу добавить новые функции, действую по собственному усмотрению, не ставя об этом в известность Microsoft, чтобы они что-то переделали или просто учли этот факт. Если хотите оставаться в курсе моих соображений относительно .NET и знать об изменениях в этой книге, подпишитесь на бесплатную информационную рассылку Thunderclap («Ужасная новость») на моем web-сайте www.rollthunder.com. В какой-то момент вы, несомненно, скажете: «Черт возьми! Платт абсолютно прав (или не прав)! Надо бы, чтобы Microsoft изменила то или добавила это». В Microsoft будут рады услышат ваше мнение. Например, в главе 3 я объясняю, что в соответствии с текущими планами Microsoft предполагает, что вы должны использовать Блокнот (Notepad) для настройки ASP.NET. Я спорю с ними, объясняя, почему это просто неприемлемо для админист-
Введение
13
раторов в реальной работающей среде. Если вы со мной согласны и считаете, что это нужно исправить, направьте свои соображения в Microsoft. Мы все рады вашим замечаниям на всех стадиях разработки!
Песнь Интернету Современная поэзия сводит меня с ума. ПоСовременная поэзия — чти вся она для меня неотличима от напы- полный боеа пленной политизированной прозы с рассыпанными там и сям возвратами каретки. Ни рифмы, ни ритма, — только автор (обычно с личными доходами или с грантом за счет налогоплательщиков, иначе он бы умер с голоду) у которого фатальная мания, что Он Должен Сказать Что-то Важное. Может, мой скромный интеллект просто не хочет предпринимать усилии, чтобы разобраться в его умственных отклонениях. Не знаю, как вы, а я найду другое применение немногим оставшимся у меня извилинам. Вместе с тем я люблю старую поэзию, особен_ Поэзия, Киплинга но Киплинга. По нынешним временам полит- ппекоасна корректным его не назовешь (прочтите его поэму «Бремя белого человека», если хотите знать почему). В его защиту могу сказать, что все мы — продукты своей эпохи. И он получил Нобелевскую премию по литературе в 1907 г., так что кому-то он тогда должен был нравиться. Дедушка и бабушка подарили мне его книгу «Вот так сказки». Мои родители читали мне ее перед сном и по ней я сам учился читать. Я изучал поэзию Киплинга в школе, заметив, что читать раздел в хрестоматии с его стихами гораздо интересней, чем слушать учителя. Его стихи до сих пор звучат во мне как никакие другие ни до, ни после. Вы спросите, какое отношение это имеет к Киплинг написалпоэму/ компьютерному безумию? Невероятное уско- прославляя флотского рение технологических инноваций в после- инженера, и почти все, дние годы заставили меня вспомнить поэму о чем он говорил, отноКиплинга «Молитва МакЭндрю», опублико- сится к сегодняшним программистами, ванную в 1894 г. Многие считают, что совре- :;:,; менность сильно отличается от прошлого, особенно, когда речь идет о технологиях. И все же я поражаюсь, насколько ощущения
14
Глава 1
МакЭндрю совпадают с моими сегодняшними. Главный герой — старый шотландский морской инженер — размышляет о наиболее блестящем технологическом достижении своих дней — корабельном паровом двигателе. Это было началом смерти расстояний — процесса, который я и вы, мои дорогие чудики, доведем до конца, прежде, чем обретем вечный покой. Мне так нравится эта поэма, что каждую главу я начинаю с цитаты из нее. Полностью вы ее можете прочитать на http://home.padfier.com/~rboggs/ KIPLING.HTML. Может, вы думаете, что прототипом шотландских инженеров является Скотти из фильма Star Trek, но я уверен, что Джен и Роденберри взял за основу киплинговского МакЭндрю, ;
Например, каждый программист знает форЭта поэма сооержит раннюю формулировку мулировку закона Мура, так? Он гласит, что закона Мура. '. вычислительная мощность за данную цену удваивается каждые восемнадцать месяцев. Многие знают и его опровержение — закон Гроша, который утверждает, что как бы ни старались ребята-железячники, ребятапрограммисты все равно сведут их усилия на нет. Многим известно даже следствие Яблокоу, которое формулируется очень просто: «И это не предел». Но МакЭндрю постиг это сто лет назад, куда раньше, чем некоторые плагиаторы прилепили к этой идее имя Мура и назвали ее законом. Когда я смотрю на старую добрую IBM PC с частотой 4,77 МГц (два флопа и 256 Кбайт памяти), я вспоминаю слова Киплинга: Он начинал еще тогда — в машинном на подхвате! Не пароход был в те года — труба на самокате! Давленье — десять фунтов. Смех! Иначе не назвать. Теперь мы выдадим на всех аж сто шестьдесят пять! Мы ковырялись так и сяк с убоищем мотора, Л ведь на тридцати узлах работать будем скоро! Подобно Родни Дэнжерфилду4 мы жаждем почета и признательности. Человечество смотрит на нас косо с тех самых пор, как первый пещерный программер исследовал заостренный камень и сказал: «Классная фрактальная структура. Интересно, что если масштабировать его до размеров наконечника для копья?» Помните, как одноклассницы толпились вокруг футболистов, больПопулярный в США комик. — Прим. перев.
Введение
15
шинство из которых {не все, Брайан) были немы, как стена? Отличники, как правило, были не интересны (я не исключение), и даже мои шахматные награды не подкреплялись университетским дипломом. Хотя я теперь и знаю, что в перспективе я заработал гораздо больше денег, чем мои разгильдяи-одноклассники (которые, по мнению моего отца, пользуются большим успехом у противоположного пола), мне все еще больно. МакЭндрю в голос рыдал о том же, только гораздо красноречивей (выделено мной): Романтику ему подай! Проклятый первый класс! — Да в чистых томиках издай. — Л кто споет про нас? Любовь и кровь, любовь и кровь — тошнит от перегара! О Боже, нужен новый Берне, чтоб создал песню Пара! Я не Берне, и даже моя матушка затыкает уши, когда я пою. Но я приложу все усилия, чтобы рассказать эту историю так, как я ее вижу. Надеюсь вы получите удовольствие от чтения.
Глава 2
Объект! Басами поршни зазвучат, а помпы — чуть визгливо, Эксцентрики заголосят, и заскрежещут шкивы, И передачи подадут свой глас в свой миг и час, И вал —услышишь! — подпоет, в великий хор включась. Вот это песня! В ней напор, и слаженность и сила. Р. Киплинг о чрезвычайном разнообразии типов компонентов, гармоничная работа которых необходима для функционирования каждого приложения. («Молитва МакЭндрю», 1894 г.)
Суть проблемы Хорошие программы писать трудно — так Хорошие программы было всегда. А сложность проблем, которые Ьцсать нелегко приходится решать разработчикам при создании полезных приложений, в современном распределенном и гетерогенном мире Интернета возросла. Иногда я ловлю себя на ностальгии по старым добрым временам, когда под разработкой ПО понимали создание процессора вводимой информации, который, анализируя считанные прямо с клавиатуры коды, преобразовывал их в понятные командному процессору символы. Теперь все не так. В настоящее время разработчиков постоянно преследует ряд сложнейших проблем. Во-первых, выбирая язык программирования, мы сразу же столкнемся с противоречием. Хотя теоретически на любом языке можно создать программу, которая задействует все преимущества ОС, уж слишком часто приходится слышать: «Эй, парень, если 2—1760
18
Глава 2 ;
Все системные функции оолжны быть доступны в,любом языке фаграммирован-ия. ;|
ты пишешь на COBOL'e, то не сможешь использовать автоматическое управление памятью. Пора бы тебе перейти на настоящий язык». Хотелось бы, чтобы выбор языка определялся тем, насколько хорошо он подходит для реализации прикладной области, а не соответствием возможностям системы — хватит нам граждан второго сорта! Думаю, что, если все крутые возможности Java были бы доступны лишь в Java, это стало бы причиной его скорого заката. Терпеть не могу, когда кто-нибудь настойчиво утверждает, что, дескать, принимаю лишь Единственный Истинный Язык Программирования. Я считаю, что Спасение должно быть доступно адептам всех «вероучений» от программирования.
После выхода в 1993 г. технологии СОМ разТехнология СОМ , .... . позволила разрабаты- работчики ПО для Microsoft Windows поняли, еать приложения путем что им больше не надо писать весь код присборки их-шкоммер- ложения «с нуля». СОМ позволяет клиенту чески доступных комгю- вызывать функции сервера на уровне двоичнентов, одо&жеря от ного не б компилпции исходного необходимости писать ; _ _ ,-,,-, все «с нуля» текста. В СОМ прикладную логику ПО можно реализовать с помощью компонентов, купленных у сторонних поставщиков (например, элемента управления «календарь») и подключенных к приложению через сравнительно тонкий слой связующего кода. Это позволяет быстрее разрабатывать приложения, функциональность которых лучше, чем у самостоятельно написанных программ, а сторонним компаниям — намного повысить удельную стоимость для амортизации своих затрат на разработку. С помощью COM Microsoft также предоставила доступ к функциональности ОС (в частности, к организации очередей и транзакциям), что также ускоряет работу приложений и облегчает их создание. Идея была неплоха, и программные боги стали благосклонны. На время...
До сих пор мы обходились СОМ Теперь же требуется абстрагироваться от различии а реализации.
: Как и в случае большинства архитектур ПО. г ' с п омощыо СОМ удалось в определенной мере облегчить ситуацию. Но теперь ее внутренняя структура из вспомогательного фактора превратилась в источник затруднений. V СОМ две главные проблемы: во-первых,
Объекты .NET
19
она требует от приложения развитой инфраструктуры, например, фабрик классов и преобразователей интерфейсов. В каждой среде разработки эти механизмы реализованы по-своему, поэтому они несколько отличаются и не настолько совместимы, как хотелось бы. Во-вторых, клиент и сервер СОМ взаимодействуют на расстоянии. Их взаимодействие основано на внешних интерфейсах, а не на сходстве внутренней реализации. Можно сказать, что у клиента и сервера СОМ «любовь по телефону». Увы, отличия между реализациями интерфейсов СОМ коварны и трудно согласуемы. Например, в C + + строки реализованы иначе, чем в Microsoft Visual Basic, а строки в Java отличаются и от С + +, и от Microsoft Visual Basic. При передаче строки от сервера СОМ, написанного на Visual Basic, клиенту, написанному на C++, кто-то должен сглаживать эти отличия. Обычно это делают приложения на С+ +, поскольку реализация из Visual Basic инвариантна. V программистов уходит куча времени на устранение отличий в реализации. При этом много времени пропадает зря (кроме того, это надоедает программистам, которые стремятся заняться чем-нибудь повеселее), и вы никогда не узнаете наверняка, будут ли все клиенты СОМ работать с вашим сервером, невзирая на их реализацию. Необходимо сгладить эти различия, допуская более тесное взаимодействие приложений. Web no своей сути гетерогенна, гомогенная : ,- Хотелось бы, чтобы Web — это ничто. Это доминирующее свой- Наши программы ство должно учитываться в архитектуре лю- работали на самых бой программы, претендующей на успех. разных платформах. Хотя Microsoft и желала бы повсеместно видеть ПК под управлением Windows, стало очевидно, что этого не будет. Желательно, чтобы однажды написанное ПО работало на самых разных платформах. Этого ожидали от Java, но ожидания оправдались не полностью {только не надо электронных писем, полных праведного гнева и возражений,— это МОЯ книга). Даже если сегодня мы не можем использовать этот подход в полной мере, в будущем хотелось бы иметь возможность развития интероперабельности платформ. Утечки памяти сегодня — одна из самых существенных причин сбоев программ, особенно тех, что работают в течение долгого времени. Случается, программист выделяет в ОС блок памяти с
20
Глава 2
А томя-шчегкпе ^ намерением освободить его позже, но забы вает это управление памятью сделать и выделяет следующий блок. должно предотвратить Тогда говорят, что произошла «утечка» блоутечки памяти. : ка памяти, поскольку в дальнейшем его уже ш не используешь. Если приложение работает долго, «утечки» накапливаются, и ему не хватает памяти. Это не важно в случае таких программ, как Блокнот, которые пользователь запускает всего на несколько минут и после закрывает, но фатально для таких приложений, как Web-серверы, которые должны непрерывно работать в течение дней и недель. Можно следить за освобождением каждого выделенного блока, но все равно в программах со сложной логикой блоки часто теряются. Нужен такой механизм борьбы с утечкой памяти, о котором просто нельзя забыть; он должен быть как автоматический ремень безопасности, который невозможно забыть пристегнуть. I Ни один продукт не достигает совершенства Требуется помощь при к управлении различными ,: моменту начала поставок. (Знаю, знаю: версиями одного ц того ваши достигают, но согласитесь, что все осже пакета ПО. \ тальные — нет, да? Кроме того, как без обновлений получить дополнительные деньги за уже проданное ПО?) Спустя некоторое время после выхода первой версии вы начинаете поставлять обновленную версию продукта с новыми функциями и исправлениями ошибок в старых, После этого начинается веселье: не важно, сколько усилий вы затратили на поддержку преемственности нового выпуска со всеми старыми клиентами, на деле это осуществить очень трудно и практически невозможно испытать. Как было бы здорово иметь механизм, используя который, серверы публиковали бы сведения о версии их ПО. Было бы неплохо, если б эти механизмы позволяли клиентам читать сведения о версиях ПО всех доступных серверов и выбрать совместимый или, при отсутствии такового, точно определить отсутствующие компоненты. Благодаря таким методикам, как классы и наследование, ООП проникло в мир разработки ПО- Программы, сложность которых превышает определенный не слишком высокий уровень, можно создавать лишь по этим методикам. К сожалению, все языки поддерживают очень разные сочетания функций ООП, которые в силу естественных причин несовместимы. Это значит, что взаи-
Объекты .NET
21
модействие различных языков возможно у _ .л лишь на очень низком уровне абстрагирова- фшшии ООП 6ыл« ния. Например, СОМ не позволяет програм- доступны не только во мистам на Visual Basic расширять функцио- всех языках, мо и чтобы нальность объектов, написанных на C++ с фу»кщш ООП одного помощью удобных механизмов наследова- . из другого, ния. Вместо этого приходится обходить эти k ограничения, применяя громоздкие механизмы. Хотелось бы, чтобы функции ООП были доступны не только в каждом языке, но и чтобы функции ООП одного языка были доступны в другом. Web очень быстро становится для пользоваИз'соображениО • : телеи главным средством получения ПО, что безопасности нужна ведет к возникновению серьезных проблем возможность огракичев области безопасности. Хотя в текущих вер- нш действий фрагмен3 Т сиях Windows автор загружаемых фрагмен- тов ^З ' к ^ °рь1м нет полного ооверия. тов кода идентифицируется с помощью циф- ; ровых сертификатов, в настоящее время невозможно гарантировать, что какая-либо программа не нанесет ущерба системе, скажем, зашифровав файлы. Можно решить, устанавливать загруженную программу или нет, но после этого нет ни одного приемлемого способа ограничить ее действия. Такое решение типа «все или ничего» на самом деле неприемлемо. Хотелось бы, чтобы в нашем распоряжении был какой-то механизм, позволяющий устанавливать для различных программ разрешенные и запрещенные действия, а ОС могла бы реализовать эти ограничения. Скажем, только что загруженной программе можно было бы разрешить чтение файлов, но запретить запись. По мере роста ОС Windows стала невообра- i Нужен лучший способ зимо сложной. Будучи вначале скромным ^шзацм.функций сервером игры «Пасьянс» с парой сотен фун- ОС для облегчения кций, она выросла в чудовищный сервер л рабшыснцми, «Свободной ячейки», у которого более 5 000 п функций. Нужную функцию просто невозможно отыскать в алфавитном списке — на это уходит слишком много времени. Программисты управляют сложными проектами, организуя ПО в логические объекты. Чтобы получить хоть какой-то шанс найти нужную функцию, нужен аналогичный способ организации функций ОС в логически связанные группы.
22
Глава 2
В конце концов я вовсе не хочу принижать Новая объектная модель;должна -бесшовно значение СОМ. Для своего времени это была влшмодейс10овать революционная технология, и значительная с СОМ, как в качестве ее часть останется с нами в обозримом бу,клиента, так и сервера. дущем. Подобно первым цветным телевизорам, которые должны были принимать не только цветные, но и преобладавшие в то время черно-белые передачи, новая объектная модель должна бесшовно взаимодействовать с СОМ, как в качестве клиента, так и сервера. Должно быть ясно, что столь длинный список требований не в состоянии реализовать самостоятельно ни один отдельно взятый разработчик приложений. Здесь мы достигли потенциального предела. Чтобы перейти в мир Интернета, требуется больше сил, чем нам может дать мир, в котором мы живем.
Архитектура решения .NET Framework — это продукт для ОС, со Решение заключается'8 , использовании, управля- зданных Microsoft, который предоставляет емоео кода, исполни- готовые решения для перечисленных проемого. под управлением' блем при программировании. Ключевым по;€LR (Common language нятием этой платформы является управляе| мый код (managed code). Управляемый код работает в среде CLR (Common Language Runtime), которая поддерживает более богатый набор служб, чем стандартная ОС Win32 (рис. 2-1). Среда CLR дает нам большую мощь, позволяющую нашим программам выжить в суровом и диком мире, которым является программирование для Интернета в настоящее время.
;
Но как может CLR, обладая такой архитектурой, работать с любым языком? Звучит не очень убедительно, но это зависит от вашего определения термина «язык». Любой инструмент разработки, совместимый с CLR, компилирует свой исходный текст в программы на стандартном языке Microsoft Intermediate Language (MSIL или, для краткости, IL) (рис. 2-2). Поскольку независимо от языка исходного текста все инструменты разработки выдают программы на одном и том же языке — IL, все различия в их реализации исчезают к моменту достижения CLR. Независимо от формы представления строк в исходном тексте на самом языке
Объекты .NET
'
программирования их внутренняя реализация одинакова в любых программах, так как в CLR все они используют объект String. To же самое верно в отношении массивов, классов и всего остального. Управляемый кпд" '
CLR
•f
i/ Новые функции, присущие исключительно CLR, например, сбор мусора
Запросы существующих функций, например, на открытие файла, исполняемые при посредничестве CLR . ' ~~ОС Win 32 •
Рис. 2-1. Управляемое исполнение программы в CLR. Инструменты разработки, такие как Visual Studio.NET Исходный код на Visual Basic, Visual С+- +, COBOl и т. д.
Just-in-time компилятор .
Microsoft Intermediate Language (MS1L)
Код, специфичный для платформы
Рис. 2-2. Исходные тексты на различных языках компилируются в программы на MSIL. Любая компания может создать язык, совместимый с CLR. В Microsoft Visual Studio.NET входят CLR-созместимые версии Visual Basic, C# (произносится как «Си-шарп»), JScript и C + + . Сторонние компании также создали много других языков, среди которых APL, COBOL и Perl.
Исходные тексты на любом языке, совместимом с CLR, компилируются в программы на едином промежуточном языке.
Код на IL, созданный инструментом разраДля запуска на целевой' ботки, не может сразу работать ни на каком машине исходмыО тексткомпьютере. Для этого требуется следующий на IL компилируется по, шаг — компиляция по требованию (just-in- требованию (just-in-tirne). time, JIT) (рис. 2-2). Утилита компилятор по требованию (just-in-time compiler илиУ/Tter) читает исходный текст на IL и производит настоящий машинный код, способный рабо-
24
Глава 2
тать на данной платформе. Благодаря этому .NET в некоторой степени независима от платформы, коль скоро для каждой платформы существует свой JITter. Microsoft не создает вокруг компиляции по требованию большой шумихи, какую создала Sun вокруг Java пять лет назад, поскольку эта функция еще не вышла из яслей. В настоящее время анонсирована лишь реализация CLR для Windows 2000, но я ожидаю, что через некоторое время появятся и другие. Эта стратегия рассчитана скорее на поддержку будущих версий Windows типа грядущей 64-разрядной версии и Windows XP, чем других ОС, например, Linux. .NET Framework поддерживает автоматичес.NcT f ramework nogqep- ; •• живает автоматическое кое управление памятью с помощью механизуправление памятью мэ, сбор мусора (garbage collection). Програм• с помощью методики ма не обязана явно освобождать выделенную '• для нее память. CLR определяет, что память «сбор мусора». • -i^i-f больше не используется программой и автоматически повторно использует ее. Хотел бы я себе прислугу, которая так же стирала бы мое белье! Наконец, .NET Framework поддерживает уп.NET Framework _ . ,. ' , поддерживаетяэное равление версиями. Технология Microsoft стандартизированное -NET дает разработчикам серверов стандаруправление версиями. , тизированный способ указания версии (эти сведения находятся в конкретном ЕХЕ или DLL-файле) и стандартизированный механизм, позволяющий клиенту указать нужную ему версию. ОС будет поддерживать запросы клиентами сведений о версии с помощью базового набора функций управления поведением, допуская их подмену разработчиком и позволяя в явном виде задавать поведение при управлении версиями. Поскольку в результате компиляции ucxoq' любом языке получаются текс ™ на IL, все поддерживающие CLR языки потенциально поддерживают одинаковый набор функций. Хотя в принципе можно создать язык, совместимый с CLR, который не будет показывать программисту какие-либо лежащие в его основе функции CLR, думаю, что в этих безжалостных дарвиновских джунглях, коими
.NET Framework расши- вает сферу применения богатого набора функ- ции ООП на все языки,
ных текстов на
Объекты .NET
25
является современный рынок ПО, эта нездоровая идея быстро отомрет. CLR поддерживает богатый набор функций ООП, в частности, наследование и создание объектов с параметрами. Не пугайтесь, если на слух эти понятия покажутся вам сложными — зато они просты в использовании. Они сэкономят вам массу сил, избавят от многих потенциальных ошибок и со временем понравятся вам. .NET Framework организует функциональ- ' ns~ . NET Framework органы- = ность ОС посредством пространства имен ^ функциональность : System. Все объекты, интерфейсы и функции системы в иерархичес-'' ОС теперь иерархически организованы, так кое пространство имен. что искать нужные вещи стало гораздо легче. Это также исключает конфликты имен между объектами и функциями, созданными вами, объектами и функциями самой ОС и созданными другими разработчиками. .NET Framework поддерживает безопасность .NET Framework доступа к коду. Можно разрешить выполнять поддерживает определенные действия одной программе и безопасность кода, запретить другой. Скажем, программе можно разрешить чтение файлов, но запретить запись. CLR реализует заданные ограничения и блокирует любые попытки выйти за их пределы. Это значит, что к полученному из разных источников коду можно применять разные уровни доверия аналогично тому, как вы no-разному доверяете людям, с которыми имеете дело. Это позволяет работать с кодом, загруженным из Web, не беспокоясь за целостность системы. Наконец, .NET Framework поддерживает бес, .NET Framework обеспешовное взаимодействие с СОМ как в каче- чивает бесшовное стве клиента, так и сервера. .NET помещает езаимодействиееСОМ объект СОМ в объект-оболочку, в результа- как в качестве клиента, те первый воспринимается как встроенный ^ ,, так и сервера, объект .NET. Это значит, что у кода .NET нет сведений об объектах, с которыми он работает, да это и не суть важно. С другой стороны, объекты .NET знают, как регистрироваться на определенном уровне абстрагирования, что позволяет клиентам СОМ воспринимать их как серверы СОМ.
26
Глава 2
Вот так... И почем все это? А как быть со вторым законом Платта («Ко Становится see сложнее создавать ОС, но-вам на *ичество неприятностей во Вселенной постосамом деле не стоит об янно», см. главу 1)? Если у меня стало меньэтом беспокоиться- ше проблем (скажем, мне больше не нужно заботиться об освобождении выделенной памяти), они не исчезли бесследно и обязательно падут на чьюто голову. В случае .NET эти проблемы свалились главным образом на две группы голов: сотрудников Microsoft и Intel (все мои читатели, работающие в Sun, вскочили с радостным воплем). Для Microsoft создание ОС усложнилось. Написать автоматический сборщик мусора вроде того, что содержится в .NET, на несколько порядков сложнее, чем простой диспетчер кучи вроде встроенного в Windows 2000. Поскольку Microsoft надеется продать несколько миллионов копий .NET, корпорация может позволить себе нанять много умных программистов и инженеров. Такое разделение труда — оставить Microsoft все заботы по разработке инфраструктуры — очень неглупо с экономической точки зрения. .NET Framework заставит Intel выпускать более быстрые процессоры и больше чипов памяти. Кое-кто из отдела маркетинга Microsoft утверждает, что .NET-приложения рабо™ ™ - ^стро, как прочие, но это не так, и никогда так не будет. Сложный механизм сбора мусора требует больше вычислений, чем простое выделение памяти из кучи аналогично тому, как в автоматическом ремне безопасности больше деталей, чем в ручном. Кроме того, поскольку сбор мусора производится не так часто, придется увеличить память компьютера, чтобы ее хватило приложениям, в то время как остается достаточно «мусорных» объектов, подлежащих уборке. (Помните закон Гроша? Если нет — загляните в конец главы 1.) Не думаю, что дополнительная память и циклы процессора будут потрачены программой .NET впустую, как в Офисе на танцы дурацкой скрепки. Думаю, они будут разумно вложены, что сэкономит, таким образом, ваше время и деньги, позволяя писать программы быстрее и снижая число ошибок в них, поскольку большая часть грязной работы достанется ОС. Приложения, использующие обычную дисковую ОС, никогда не
Выадслителькые задачи тоже усложняется — соответственно растут требования к
Объекты .NET
27
будут работать так же быстро, как те, что программируют движения головок жесткого диска (указывая сектор и дорожку). Но это непозволительно, так как занимает слишком много времени, стоит чересчур дорого и не позволяет обработать достаточно много данных. Можно потратить все свое время на глупые операции с дисковыми секторами и никогда не кончить работы, за которую платят. Как только появляется возможность абстрагироваться от проблем, связанных с инфраструктурой, это становится потребностью. Если ваш диспетчер памяти работает довольно сносно, вы сэкономите время при отладке, отслеживая утечки памяти.
Простейший пример Я написал простейшую программу, чтобы на ; ' . Здесь -начинается ее примере продемонстрировать принципы рассмотрение примера работы .NET Framework. В дальнейшем по объекта .NET Framework, ходу книги я буду поступать так же. Этот пример, как и другие программы из этой книги, доступны по адресу www.introducingmicrosoft.net. Я написал объект-сервер .NET, .NETальтернативу библиотеки ActiveX из Visual Basic 6 и соответствующий клиент. Сервер поддерживает единственный объект, имеющий единственный метод — GetTime, который в виде строки предоставляет текущее системное время с секундами или без них. Даже несмотря на то, что сервер написан на Visual Basic, а клиент — на С#, мне не пришлось задействовать Visual Studio. Честно говоря, оба приложения я писал в Блокноте и компоновал их, используя инструменты командной строки из состава .NET SDK. В других разделах этой главы я обязательно приведу примеры применения Visual Studio.NET. Копия .NET SDK доступна по адресу www.msdn.microsoft.com/net. Ниже приведен пример объекта-сервера Г Vis^B a5tcm (рис. 2-3). По крайней мере на первый взгляд ^ш^д существенных он напоминает программу, написанную на отличибот Visual Basic 6. классическом Visual Basic. Однако в версию Visual Basic, которая вошла в .NET, Microsoft внесла ряд важных изменений, позволивших ей работать с классами CLR из .NET и корректно взаимодействовать с другими языками CLR. Подробное обсуждение этих изменений выходит далеко за рамки этой
28
Глава 2
книги, но для примера скажу: теперь индексация элементов массивов начинается не с 1, а с 0. Если объявить массив с 10 элементами (Dim x (10) As Integer), его члены будут пронумерованы числами от 0 до 9 вместо 1-10, как вы привыкли. В сражении между ребятами, программирующими на C++ и VB, за то, чей синтаксис массивов лучше соответствует CLR, победа за С++никами. Увы, но эти изменения означают, что корректная работа существующих программ на VB после простой перекомпиляции в Visual Studio.NET невозможна. Вопреки вашим надеждам приведение программ в соответствие с требованиями .NET потребует определенных, но не слишком больших усилий (см. последние новости в примечании в конце этой главы).
Примечание Т"
""
""-"
""'
"
'..
""","
, ;" ,"Г
'~
' ';•
В Visual Studio.N-ET ёходит средство обновления, которое •:';: автоматически запускается, когда вы открываете проект ; Visual Basic 6. Оно помечает обнаруженные необходимые изменения и предлагает исправления. Определенно, язшк = стал более мощным. Можно решиться на переход к .NETизза крутых возможностей по поддержке Интернета. Даже " если вы пишете только однопользовательские автономные приложения для обработки форм, причинами перехода могут быть поддержка управления версиями, облегченйоё развертызание и освобождение ресурсов. При взгляде на исходный текст нашего объекта-сервера прежде всего заметна директива Imports. Эта новая директива языка Visual Basic.NET заставляет компилятор «импортировать пространства имен». Термином пространство имен (namespace) обозначают описание набора готовой функциональности, поддерживаемого некоторым классом в некотором окружении. Концептуально он идентичен ссылке в проекте Visual Basic 6. Список имен наборов функциональности, следующий после директивы Imports, задает наборы функциональности, ссылки на которые должны быть включены исполняющим ядром. В данном случае Microsoft.Visual Basic— это ссылка, содержащая определение функции Now, которая служит для получения значения времени. При использовании языка Visual Basic в Visual Studio.NET пространство
Объекты .NET
29
имен Visual Basic импортируется автоматически, для этого не требуется указывать оператор в явном виде. ' Импортировать внешнее пространство имен Visual ' Basic, чтобы получить возможность обращаться к 1 функции Now по ее сокращенному имени. Imports Microsoft. Visual Basic 1
Объявить пространство имен, с помощью которого клиенты смогут получать доступ к классам этого 1 компонента. 1
Namespace TimeComponentNS ' Объявить класс(ы), которые будет предоставлять ' клиенту эта DLL. ' Это делается так же, как и на VB6. Public Class TimeComponent 1 Объявить функцию(и), которую(ые) этот класс ' будет предоставлять клиенту. ' И это делается так же, как и на VB6.
Public Function GetTime (ByVal ShowSeconds As Boolean) _ As String ' В силу некоторых причин форматирование дат и 1 возврат значений функций в Visual Basic.NET 1 различны. If (ShowSeconds = True) Then Return Now. ToLongTimeString Else Return Now. ToSnortTimeString End If End Function End Class End Namespace Рис. 2-3. Листинг исходного текста простейшего объекта-сервера.
30
Глава 2
Далее мы видим директиву Namespace TimeComponentNS. Она объявляет пространство имен моего компонента; с помощью этого имени клиенты смогут получить доступ к функциональности компонента. Пространства имен мы обсудим ниже в этой главе. Опять же, при использовании Visual Studio.NET пространство имен объявляется автоматически. Далее идут объявления классов и функций, ... - J t идентичные таковым на Visual Basic 6. Наконец, я разместил во внутренней логике получения времени операторы для форматирования его значения в строку и возврата строки клиенту. Эти операторы несколько различны. Свойство Now no-прежнему получает дату, но форматирование в строку теперь производит метод нового класса DateTime, а не отдельная функция. Значение, возвращаемое функцией Visual Basic, теперь задается новым ключевым словом Return, что отличается от синтаксиса, применявшегося в ранних версиях.
8 этом разделе • приводится описание • объекта-сервера.NET.
Затем инструментами командной строки из Г При компиляции исход- NET .,_.,-,.,-,,, SDK я ных текстов «а яэцче ' скомпилировал исходный текст в Visual Baste получаются DLL, которую назвал timecomponent.dll. Те, ОН, содержащие II У кому нужен образец синтаксиса командной и метаданные. строки, найдут его в программе-примере, загруженной с сайта книги. Полученная в результате библиотека может показаться обычной DLL, но внутри она устроена совершенно иначе. Компилятор Visual Basic.NET не преобразует код Visual Basic в машинные коды (команды, специфичные для вашего процессора). Вместо этого логика моего объекта-сервера в DLL выражена на IL, промежуточном языке, с которым мы познакомились в разделе «Архитектура решения». Все компиляторы языков CLR выдают вместо машинных кодов процессора исходные тексты на IL. Это позволяет CLR бесшовно работать с множеством различных процессоров. Полученная DLL также содержит метаданные (metadata), т. е. описание кода для системы CLR. Формат метаданных, необходимый для описания содержимого DLL, определяется CLR: они содержат сведения о том, какие классы и методы хранятся в DLL, какие внешние объекты ей нужны, какую версию программы она представляет и т. д. Ее можно рассматривать как библиотеку типов, накачан-
Объекты .NET
31
ную анаболиками. Главное отличие в том, что сервер СОМ иногда должен работать без библиотеки типов, тогда как сервер объекта .NET не может и подумать о том, чтобы работать без своих метаданных. Эти метаданные мы обсудим в разделе «Сборки». Для проверки готового сервера нужен кли- Стёгшвъ сходства ент, Чтобы продемонстрировать тот факт, Visual Basic и С# больчто .NET работает с различными языками, я ше, чем это принято написал клиент наС#. Знаю, что в настоящее считать в сообществах время этот язык знаком немногим, а может, программистов, использующих эти языки. и никому из вас. Но если взглянуть на следующий код (рис. 2-4), станет ясно, что на таком уровне сложности разобраться в нем можно. По правде говоря, после улучшений, внесенных в Visual Basic. NET для поддержки функции ООП, таких как наследование (см. ниже), мне доводилось слышать, как программисты после пары кружек пива называли С# «VB с ;» или даже «Java без Sun», За любой из этих эпитетов легко схлопотать, если произнести его слишком громко, перепутав бары в Редмонде и Саннивэйле. Исходный текст примера клиента начинается с импорта пространств имен, для этого на С# требуется указать директиву using. Наш клиент импортирует пространство имен System (его подробное описание см. ниже), которое содержит описание функции Consoie.Write и пространство имен нашего компонента time. Надо явно указать компилятору DLL, в которой расположено пространство имен, что можно сделать в пакетном файле компилятора. Для этого также служит удобный пользовательский интерфейс Visual Studio.NET. Исполнение любой Сопрограммы начинается со статического метода Main. Видно, что в нем наша клиентская программа с помощью оператора С# new дает указание исполняющему ядру CLR отыскать DLL, содержащую класс Time Component:, и создать его экземпляр. В следующей строке вызывается метод этого объекта GetTime. Затем системный метод Consoie.Write выводит значение времени в окне командной строки. В этом случае компилятор С# создает ЕХЕ-файл. Подобно DLL сервера, этот ЕХЕ-файл содержит не машинные коды, а промежуточный язык и метаданные.
32 // // // //
Глава
Импортировать пространства имен, которые использует эта программа, чтобы получить возможность обращаться к их функциям по сокращенным именам.
using System ; using TimeComponentNS ; class MainApp i // Статический метод "Main" является точкой // входа в приложение. public static void Main () // Объявить и создать новый компонент класса, // который поддерживается сервером, // написанным на VB. TimeComponent tc = new TilneCoinponent () ; // Вызвать метод сервера GetTime. Вывести // результирующую строку в консольном окне. Console. Write (tc. SetTime (true)) ;
Рис. 2-4. Исходный текст на С# простейшего клиента объекта, При запуске исполняемого файла клиента, При компиляции _ „ клиента, написанного написанного на С#, системный загрузчик на С#, тоже получается определяет, что это управляемый код, и пефзилсП, редает его ядру CLR. Ядро, обнаружив IL в ЕХЕ-файле, вызовет компилятор по требованию (just-in-time compiler или JITter). JITter — это системный инструмент, который преобразует IL в машинные коды любого процессора и ОС, под управлением которой он работает. Для каждой архитектуры есть со6стзенный]1Т1ег, соответствующий особенностям конкретной системы. Благодаря этому один и тот же набор IL-инструкций может работать на системах различного типа. JITter создает машинные коды, которые начинает исполнять обработчик CLR. Когда клиент вызывает оператор new для созда-
Объекты .NET ния объекта класса Time Component, обработчик CLR вновь вызовет] liter, чтобы по требованию скомпилировать IL из DLL компонентов, а затем выполняет вызов и возвращает результат. При этом выводится следующая информация (рис. 2-5). 02 .'И'../2881 в9:11,|
нннввзнш C:VNH honk 1в:2>,:43 ЙМ С:ЧН1Л bo ok \
Рис. 2-5. Информация, которую выводит на консоль программа TimeCSient. Модель компиляции в период выполнения Исходный текст на It неплохо работает в случае некоторых классов , компилируется ;' приложений, например, программы на Инпо требованию при клиента; или его тернет-странице, на которую еы только что комтеэнентов.' зашли. Но для других приложении она подходит хуже, например, для Visual Studio, которой еы пользуетесь семь дней в неделю и обновляете ее раз или два в год. Поэтому можно указать, что JIT-компиляцип приложения должна осуществляться только раз при установке его на машину, а полученный при этом машинный код будет храниться в системе, как обычное приложение. Это делает утилита командной строки Ngen.exe (native image generator), которая в этом примере не показана. Как загрузчик узнает местонахождение DLL сервера, когда клиент создает объект с помоDLL в каталоге клиентсщью оператора new? Он просто ищет ее в кого каталоге, где находится клиентское приложение. Эта простейшая из моделей развертывания .NET называется закрытой сборкой (private assembly). На закрытую сборку можно ссылаться только из ее каталога. Она не поддерживает проверку версий и функции безопасности. Она не
34
Глава 2
требует записей в реестре, что необходимо серверу СОМ. Все, что нужно сделать для удаления закрытой сборки, — стереть ее файлы, и никакой дополнительной очистки. Очевидно/ что, несмотря на эффективность таких простых решений в подобных ситуациях, они годятся не всегда. В частности, они не идеальны, когда одну серверную программу нужно предоставить в совместное использование нескольким клиентам. Более сложные сценарии мы обсудим ниже в разделе, посвященном сборкам.
Подробнее о пространствах имен .NET Легко выбирать
;
Помню, как, программируя для Windows 2.0,
элементы из коротких алфавитных списков.
я просматривал алфавитный список функции ОС (отпечатанный на бумаге — вот как давно это было!), пока не находил какую-нибудь функцию, чье имя напоминало мне предмет поиска. Я пробовал задействовать ее, иногда получалось, иногда — нет. Если функция не работала, я опять лез в список. Организовать в алфавитный список несколько сотен функций Windows 2.0 было довольно разумно. Обычно я с первого взгляда (ну, со второго или третьего точно) замечал все, чем мне может быть полезна ОС, что давало мне шанс написать достойную программу, хотя и не без ограничений.
В современных 32-разрядных Windows все -По мере того, как список становится длиннее. Функции ОС просто невозможно организовсе осложняется. вать в алфавитный список. Их жутко много — больше 5 000. Я не смогу найти функции для вывода на консоль в таком чересчур длинном списке. Они разбросаны среди слишком большого числа функций, не имеющих отношения к предмету, что затрудняет их поиск. Для создателей ОС это тоже проблема. Добавляя новую функцию, им приходится выбирать для нее имя, которое должно быть описательным и не конфликтовать с именами уже реализованных функций. Прикладные программисты также должны быть уверены, что имена их глобальных функций не конфликтуют с функциями ОС. Отношение «сигнал/шум» при таком подходе снижается по мере удлинения списка функций, и на сегодня оно приближается к абсолютному нулю. Можно сказать, что пространство имен (name-
Объекты .NET
35
space), набор имен, в пределах которого любое имя должно быть уникальным, стало слишком велико. С большими списками легче обращаться, раз- = Лучший способ обработбив их на меньшие «подсписки», — их легче К7и ^льших Списко1з ~анализировать. Классическим примером та- разбиение их'нанеболького подхода может служить кнопка меню шшз логические группы. Start в Windows. Если бы приложения со всего компьютера были собраны в одно гигантское меню, вы бы никогда не нашли в нем нужное приложение. Вместо этого ужаса меню Start предоставляет относительно короткий список (что-то около 10 пунктов), который легко просматривать в поисках нужного элемента. В каждой группе есть список логических подгрупп, вложенных настолько глубоко, насколько это вам покажется оправданным. В итоге каждая из них раскрывается в короткий список реальных приложений. Чтобы запустить нужное приложение при путешествии по меню, в общей сложности приходится просматривать до 50 элементов, но их никогда не бывает больше дюжины (или около того) одновременно. Вы только подумайте, насколько это легче по сравнению с выбором нужного приложения из тысячи (примерно столько их установлено на большинстве компьютеров) с помощью единственного меню. .NET Framework предоставляет лучший спо- '^ - _ _ - В .NET используется соб организации функции и объектов ОС. понятие пространства Этот механизм исключает конфликты между имен — логической гругЬ именами функций и объектов, написанными пы, в пределах которой вами и другими разработчиками. Он основан 'Р?£ име«а уни=калы4Ына понятии пространства имен — логического подразделения функциональности ПО, в пределах которого все имена должны быть уникальны. Само по себе это понятие не ново, его десятилетиями использовали в объектно-ориентированных языках. Однако это первый известный мне случай, когда с помощью пространств имен в .NET организована вся функциональность ОС. Все объекты и функции .NET CLR являются 1 _ Все объекты и функции ; частью пространства имен System. При поис^£Т £LR «живут» в проке в документации можно заметить, что все странстве имен System, имена начинаются с символов «System». Мож- :
36
Глава 2
но сказать, что все объекты и функции, имена которых начинаются с таких символов, «принадлежат к пространству имен System». Конечно, пространство имен System довольно велико, так как оно содержит имена каждого функционального элемента из их богатого набора в ОС. Поэтому оно разделено на несколько подчиненных пространств имен, скажем, System.Console, содержащее все функции, которые имеют дело с вводом-выводом в окно консоли. V некоторых из этих подпространств имен есть еще вложенные «подподпространства» и т. д. вглубь/ пока не устанут разработчики. Полностью квалифицированным именем (fully qualified name) функции, которое иногда называют квалифицированным именем (qualified name) или q-именем (q-name), является имя, где перед именем собственно функции стоит полный путь к ней в пространстве имен, или квалификатор (qualifier). Например, System.Console. Write — это полностью квалифицированное имя системной функции, которая выводит информацию з окне консоли. Полностью квалифицированное имя позволяет вызвать функцию из любого места программы. ;Р Пространство имен System очень велико. :ч; Пространство имен System реализовано в * Поэтому оно реализовано в нескольких отнескольшх отдельных дельных DLL. Простого факта принадлежноDLL, поэтому надо -,-, сти функции или объекта к пространству I имен System недостаточно, чтобы ваш редак? тор, компилятор или компоновщик смог ее разработки «знает», что ; нужно подключить все наити' в общем случае при сборке придется необходимые DLL. ( указать инструментам разработки, какие DLL ^ пространства имен System подключить к проекту. Скажем, я часто выполняю сборку компонентов .NET в Visual Studio и при их отладке использую сообщения. Объект MessageBox является частью пространства имен System.Windows.Forms, реализованного в библиотеке System.Windows.Forms.dll. При создании проекта «Библиотека компонентов» Visual Studio не включает эту DLL в список ссылок автоматически (возможно, потому, что авторы Visual Studio полагают, что эти компоненты будут работать «за кулисами», не взаимодействуя с пользователем). Если я хочу получить в проекте доступ к MessageBox, мне приходится добавлять эту ссылку в явном виде.
Объекты .NET
37
Подобный способ организации функций в Импорт гшостранстш логические группы очень удобен и позволя- имен позволяет ет найти нужную функцию с минимумом су- вызывать его еты. Его единственный недостаток в том, что ! : полностью квалифицированные имена могут J сокращенных имен. быть очень длинны. Так, функция System.Runtime.InteropSetvices.Marshal.ReleaseComObject сразу освобождает заданный объект СОМ, не выполняя полный сбор мусора (см. раздел «Управление памятью в .NET»), В большинстве .NET-npuложений эта функций вообще не нужна, но в некоторых может использоваться многократно. Если набирать это длиннющее имя целиком каждый раз, когда нужно вызвать функцию, вы быстро выбьетесь из сил. Ведь моя жена обращается ко мне «Дэвид Сэмюэл Платт, сын Бенджамина, внук Джозефа», только когда о-оочень сердита, а в этом состоянии она бывает лишь недолго. Поэтому аналогично тому, как люди, состоящие в близких отношениях, обращаются друг к другу по имени, CLR позволяет импортировать пространство имен (рис. 2-3 и 2-4). Импортируя пространство имен, вы как бы говорите компилятору о том, что будете использовать функции из этого пространства имен так часто, что хотите перейти с ними на «ты» и обращаться по имени, Импорт пространства имен на Visual Basic выполняет ключевое слово Imports, а в Сопрограммах — ключевое слово using. Так, зыше я импортировал пространство имен System, благодаря чему смог вывести информацию на консоль, вызвав функцию Сопso/e. Write (рис. 2-4). Если бы я не импортировал пространство имен System, эту функцию пришлось бы вызывать по полностью квалифицированному имени System.Console. Write. С другой стороны, если импортировать пространство имен System.Console, я смог бы вызвать эту функцию просто как Write. Выбор пространства имен для импорта должен определяться комфортом при разработке и не влияет на конечный продукт. Он просто позволяет организовать мыслительный процесс так, чтобы получать наилучшие результаты. Поскольку вся идея отдельных пространств имен заключается в том, чтобы предотвратить конфликты путем помещения одноименных функций в разные пространства имен, нельзя одновременно импортировать все пространства имен. Во избежание путаницы я настоятельно рекомендую
38
Глава 2
определить непротиворечивый набор правил для выбора импортируемых пространств имен и следовать им на всем протяжении разработки проекта. : При написании объекта-сервера .NET слеау Ваш код также поселит- ет за ать имя ся в пространен имен пространства имен, в котором 9 под тем именем, кото- обитает ваш код. Это делается с помощью ..-., рое шх ему дадите, директивы Namespace (рис. 2-3). Часто (но не обязательно) имя пространства имен совпадает с именем файла, в котором живет программа. В одном файле может быть несколько пространств имен, и, наоборот, одно пространство имен можно распространить на несколько файлов. Часто Visual Studio.NET и другие среды разработки автоматически присваивают проекту пространство имен. Но как убедиться, что ваше пространство не будет конфликтовать с пространством имен, избранным другим поставщиком для своего компонента? С помощью сборок.
;
Сборки " В .NET Framework для хранения кода, ресур; В .NET широко исполь- 'г ,зуются яовые единицу ; сов и метаданных широко используются сборупаковки — сборки. I ки (assemblies). Весь код, исполняемый сред; ством поддержки периода выполнения .NET, должен находится в сборке. Кроме того, все функции безопасности, разрешения пространств имен и управления версиями работают для отдельной сборки. Поскольку сборки применяются часто и для самых разных нужд, мы обсудим их подробнее.
Понятие сборки Сборка — это логический набор, состоящий из одного или нескольких ЕХЕ- или DLL-файлов, в которых находятся код и ресурсы приложения. В сборку также входит декларация (manifest) — метаданные, описывающие код и ресурсы, которые находятся «внутри» сборки (чуть позже я объясню, почему «внутри» взято в кавычки). Зачастую сборки состоят из единственного ЕХЕ- или DLL-файла (рис. 2-6). DLL, которую создал компилятор при компоновке программыпримера простого сервера времени (см. выше}, на самом деле была сборкой. Вторая однофайловая сборка — это исполняемое
Объекты .NET клиентское приложение, также скомпонованное для этого примера. При использовании таких инструментов, как Visual Studio.NET, каждому проекту скорее всего будет соответствовать одна сборка.
Наши программы-примеры создают две сборки, каждая из которых состоит из одного файла.
Типы сборок
Однофайловая сборка
Многофайловая сборка
Рис. 2-6. Однофаиловые и многофайловые сборки. Хотя часто сборка располагается в одном Сборка также может файле, она может быть и логической (в пробыть логической тивоположность физической) совокупностью ' совокупностью нескольких файлов. нескольких файлов из одного каталога (рис. 2-6). Декларация с указанием файлов, составляющих сборку, может располагаться в одном из ЕХЕ- или DLLфайлов сборки, содержащих код приложения. Она также может жить в отдельном ЕХЕ- или DLL-файле, который при этом не содержит ничего, кроме декларации. Имея дело с многофайловыми сборками, надо помнить, что файлы сборки не связаны друг с другом средствами файловой системы. Ответственность зато, чтобы все перечисленные в декларации файлы были в наличии, когда их станет искать загрузчик, целиком и полностью лежит на вас. Единственный признак принадлежности файла к сборке — ссылка на него в декларации. В этом случае термин сборка не слишком удачен, так как подразумевает свинченные вместе металлические части. Возможно, термин «перечень» («roster») будет
Ю
Глава 2
более адекватным. Вот поэтому термин «внутри», упоминавшийся выше, я взял в кавычки. Утилита командной строки AL.exe [Assembly Generation Utility) из состава SDK позволяет добавлять/ удалять файлы из многофайловых сборок. Интеллектуальные среды разработки типа Visual Studio делают это автоматически. Декларацию сборки позволяет просматривать дизассемблер IL (lLDASM.exe). Декларация нашего компонента time показана ниже (рис. 2-7). В ней перечислены внешние сборки, от которых зависит данная сборка. В нашем случае она зависит от mscorlib.dll, главной библиотеки .NET CLR, а также от сборки Microsoft.VisualBasic, содержащей внутренние функции языка Visual Basic, такие как Now. Кроме того, там перечислены имена сборок, которые мы сделаем доступными из внешнего мира, в этом случае —- TimeComponent
Декларацию сборки можно просмотреть с помощью программы lLDASM.exe/
19 34 во еэ )
// .iw.
.hash = |BO 13 72 $: 14 39 DA 35 25 IA 45 OF SO 58 C3 84 60 3В ЕП 95 )
// .9.1.9.5).B. ' X . //.;..
.pub-Llckeytofcan = (ВО ЗГ 5Г IS U D5 Of. ЗА ) .haah = (A3 11 69 32 7F 24 F4 A4 OD EB 55 F9 31 63 78 BE
// . . 1 2 . S
.v=c 1:0:3411:0
// л_. U.Ic
АЭ El 91 ТВ )
.hash nlgorith™ ОнООООЯ004
f i l s alignment 512 corflags ОкООООООО! // Image Ьяэс: 0x03060000
Рис. 2-7. Декларация сборки нашего компонента Time. Кроме объектов программы, предоставляемых сборкой и необходимых ей, в декларации находятся сведения, описывающие саму сборку. Так, она содержит сведения о версии сборки в стандартизированном формате (о нем см. ниже}. Она также может описывать «культуру» (culture), для которой написана сборка (в данном случае культура — забавное название человеческих язы-
Объекты .NET
41
ков и их диалектов, скажем, австралийского английского). В случае совместно используемой сборки (мы поговорим об этом подробнее чуть позже) в декларации содержится открытый ключ, позволяющий гарантированно отличить эту сборку от других независимо от имени ее файла, К декларации даже можно добавлять собственные атрибуты, которые будут игнорированы CLR. Атрибуты декларации устанавливаются с помощью вышеупомянутой Assembly Generation Utility или в Visual Studio.NET.
Сборки и развертывание При разделении коаа по сборкам централь- 1 • Тщательно ным является вопрос: как будет использо- ТБ( ка,шм« будут ваться код вашей сборки — только вашим сборки:,закрытыми или : приложением или им и другими приложена- открытыми.. ями, которым он необходим. Microsoft.NET поддерживает оба варианта, но в последнем случае придется попотеть. Вероятно, в случае кода, написанного для собственных приложений (скажем, вычислительного ядра для сложной финансовой программы) вы захотите сделать сборку закрытой. С другой стороны, объекты общего назначения, которые по логике могут использоваться несколькими приложениями (скажем, алгоритм сжатия файлов), лучше сделать совместно используемыми. Полагаю, у вас возникнет желание сделать I • Сборки могут быть ззкk , п- сборки закрытыми — в. NET это проще проста рь£Ыми и предназмаго. По правде говоря, именно так я и посту- одшся:для определен-пил в приведенном выше примере. Для это- ! , ного приложения/что го нужно всего лишь скомпоновать простую порой может облегчить сборку как DLL и скопировать ее в каталог ; или подкаталог, где находится использующая ее сборка-клиент. Не нужно делать записей в системном реестре или Active Directory, что необходимо при использовании компонентов СОМ. При этом ни одна программа не будет изменена, если только вы сами не измените ее, так что вы никогда не столкнетесь с общеизвестной ситуацией, когда при изменении версии совместно используемой DLL приложение без видимой причины выходит из строя. Г
/
,
-
,
,
-
;
.
. -т^ДДудд^ружд
Очевидной проблемой этого подхода является возрастание числа сборок (попыткой решения аналогичной проблемы стало использование DLL в Windows 1.0). Если каждому приложению, ко-
42
Глава 2
торое использует, например, текстовое поле, потребуется собственная копия содержащей его DLL, то сборки, размножаясь как бактерии, захламят весь компьютер. В мартовском номере журнала MSDN Magazine за 2001 год Джеффри Рихтер выступил с возражениями. Он не считает это проблемой, поскольку сегодня жесткие диски объемом больше 40 ГБ продаются по цене меньше 200 долл., и каждый может позволить себе необходимое дисковое пространство. Таким образом, большинство сборок должны быть закрытыми, потому что тогда приложение никогда не выйдет из строя, если кто-то испортит совместно используемый код. Этот аргумент в стиле врачей скорой помощи, которые говорят, что мир был бы намного более приятным местом, если бы люди не напивались и не кололись. Хотя эти точки зрения абсолютно верны, ни одна из них не станет реальностью в ближайшее время. Идея Рихтера осуществима для разработчиков, у которых, как правило, есть быстрые компьютеры с большой памятью. Но клиент с обширным парком ПК двухлетней давности, который в данный момент невозможно модернизировать или просто заменить из-за отсутствия финансов, не будет покупать диски большего обьема. Довольно скоро в процессе разработке вы ощутите необходимость совместного использования сборок несколькими приложениями, и в этом вам опять поможет .NET Framework.
Однако, иногда вам могут понадобиться совместно исполъ- зуемые сборки.
.NET Framework допускает совместное использование сборок путем размещения их в глобальном кэше сборок (global assembly cache, GAC — звучит как вопли героев мультиков). GAC — это каталог на вашем компьютере (в данный момент \\winnt\assembly), где должны жить все совместно используемые сборки. Утилита командной строки GACUTIL.exe из .NET SDK, которая хорошо работает при запуске из сценариев и пакетных файлов, поможет помещать сборки в кэш, просматривать их свойства и удалять их из кэша. Большинство пользователей предпочтут программу Assembly Cache Viewer, которая является расширением оболочки и устанавливается вместе с .NET SDK. Она автоматически подключается к Windows Explorer и позволяет просматривать GAC (рис. 2-8). При совместном использовании компьютерных файлов любого типа вы постоянно рискуете столкнуться с проблемой конфлик-
Объекты .NET
43
та имен. Поскольку все совместно используГарантированная униемые сборки .NET должны быть в GAC, что- кальность имен совместбы ими можно было управлять, нужен какой- но используемых оборок то способ присвоения гарантированно уни- достигается с помощью криптографии с кальных имен всем программным файлам, открытым ключом. живущим в САС (даже если исходно у них были одинаковые имена). Это делается с помощью строгого имени (strong name), или совместно используемого имени (shared name). С помощью криптографии по открытому ключом строгое имя гарантированно уникально и отличается от имен остальных сборок в системе. В декларации совместно используемой сборки содержится открытый ключ из пары открытого и закрытого ключей. Строгое имя формируется в результате комбинирования имени файла и части этого открытого ключа.
Рис. 2-8. Средство просмотра глобального кэша сборок. Предположим, что нам требуется написать Совместно используесовместно используемую сборку, которая бу- мые сборки живут' ё'-г^р бальном кэше сборок, дет жить в САС. Для этого примера я испольадминистрирование • зую Visual Studio.NET, так как я нахожу, что эта среда разработки удобнее, чем инструляется с менты командной строки. Я написал другой специальных утилит. компонент Visual Basic.NET, выполняющий те же действия, что и простейшая программа-пример time, за исключением того, что он добавляет к строке результата символы «Shared example:», что позволяет отличить его от первого примера. После компоновки для этого компонента надо сгенерировать и присвоить строгое имя, или, иначе говоря, подписать компо-
Глава 2
44
нент. Можно сконфигурировать Visual Studio.NET так, чтобы она выполняла это автоматически (рис. 2-9). Для этого нужен файл, содержащий пару криптоключей, который позволяет сгенерировать утилита командной строки из SDK — SN.exe. При компоновке Visual Studio.NET автоматически подписала этот компонент. После этого я вручную поместил его в GAC с помощью Windows Explorer.
. , . .. r Defaults
n Props- :«
Рис. 2-9. Visual Studio.NET, генерирующая строгое имя. Кроме того, я написал клиент {на этот раз с помощью Visual Studio.NET на Visual Basic), применяющий совместно используемую сборку. Я дал указание Visual Studio.NET генери* ровать ссылку на DLL сервера, щелкнув правой кнопкой папку References в окне Solution Explorer {рис. 2-10), потом выбрал Add Reference, щелкнул кнопку Browse и нашел файл совместно используемой сборки, расположенный в стандартном каталоге.
Здесь даются f инструкции для . генерации совместно используемой сборки.
В настоящее время Visual Studio не может добавлять ссылки на сборки в GAC, но эту функцию обещали включить в следующий выпуск. Дело в том, что ко времени разработки механизма ссылок Visual Studio конструкция GAC еще не устоялась. Поэтому если разработчики не создают клиент и сервер вместе как части одного проекта, приходится устанавливать по две копии компо-
45
Объекты .NET
нентов: одну в стандартный каталог длл компиляции, а другую — в САС для работы клиента. Пользователям понадобится лишь копия в САС, Visual Studio.NET генерирует класс-ссылку, который обращается к этому пространству имен. Далее мне понадобится установить свойство Copyiocal как False, сообщив таким образом Visual Studio.NET, что локальная копия не нужна, При запуске клиента загрузчик ищет локальную копию и, если ее нет, проверяет GAC. И Reference
v£
• • •
^
I ШШЯИВЯ С- ystaC edsion s . CrystalRepc , , . • Gystaba ci5 ions , Repor tSourc e t r /i talDeds ions . Shared Hi- CrystalDetiscns.Web . Ciy^talDecislons. Windows, Fo... •Ш CrystalEnterptiseLib я! CrystallnfoStoreLIb !li: Cry5talKeyCcdeLlb 11Г CrystalPlijginMgrLib isll Cu^tomMarshaletb 1 rnviltp
2X0.9140.,., 2000.91+0,.., 2000.9140,.., Z000.9HO,.., 2000,9140..,, 1,0.0.0 1.0,0.0 1.0,0,0
L.O.Q.O
1, 0.2615. G 7.П.П.Л
•
5el t i = -«
'_:\Program Files\Common Fil. . C:\Pfogram Files^Cammon Fil.., : C:\Ptograrn Files \Commcn Fil.., - ;|C:\Prograrn Fte^Common Fil. , , ; " :: . . . ' - i I:\Program FJeslCommofi Fil. . , "• ' 1 C:\Pragram Fjle5\Conman F)... El'= = : ''.-I C:\Progr am Files\ Common Fil, . , .: C\\Pi ogramFiles^ Common Fil... ' ' i CiliwiNNTSVlMicrosoft.NETlf.,. , . - IWINNT-WMirrrrsiift NFT1F JU
Нкыешровкм ОщишШ-Йате- ' SNredTi^^ponerit.^
•'- ' Type ™ =
e -.v..-
1 SoOKe : :
-
1
tWMTMbfbiii&tfrXifi.:,:'
йетаоуй J
.~~
Рис. 2-10. Добавление ссылки на разделяемый компонент. Дополнительным преимуществом подписи В этом абзаце'даются совместно используемых сборок с помощью инструкции для написаоткрытого ключа является возможность про- ния клиента, использующего объекты из верки целостности файла сборки. Генератор сборок выполняет хэширование содержимого файлов, указанных в декларации. После этого он шифрует этот хэш вашим закрытым ключом и сохраняет зашифрованные результаты в декларации. Выбирая сборку из САС, загрузчик хэширует ее файл(ы) по тому же алгоритму, открытым ключом расшифровывает хэш из декларации и сравнивает полученные результаты. Если они совпадают, загрузчик знает, что целостность
46
Глава 2
ill файлов сборки не нарушена. Это не позво• Криптографический • алгоритм также предо- ^eT идентифицировать владельца сборки, ^стэдляег возможность так как нельзя точно установить настоящего проверки целостности владельца открытого ключа, но дает твердую файлов сборки, гарантию сохранности целостности сборки с момента ее подписи.
Сборки и управление версиями = Работа с обновлениями опубликованных про, „ грамм исторически представляет собой громадную проблему, которую часто называют «адом DLL». Замена DLL, которую использу существующий клиент, на более новую ет версию ударит вас дважды. Во-первых, новый код иногда выводит из строя имеющиеся приложения, зависимые от оригинальной версии. Как бы вы ни пытались сохранить обратную совместимость нового кода со старым, узнать или проверить, что было с этим кодом после обновления, невозможно. Это особенно раздражает, когда после установки новой DLL старый клиент (уже не работающий после этого) не запускают целый месяц, а когда это наконец происходит, очень трудно сказать, что стало причиной его выхода из строя. Во-вторых, все обновления теряются, когда при установке приложение копирует старые DLL поверх новых, уже установленных на компьютере. При этом нарушается работа имеющегося клиента, зависимого от новых DLL. В 90% случаев на вопрос сценария установки: «Существует целевой файл ххх, более новый, чем копируемый. Все равно копировать?» — пользователь отвечает «Да». Это особенно сводит с ума, когда причиной проблемы является совсем другое приложение, но в результате отказывается работать именно ваша программа, в результате ваша линия технической поддержки принимает дорогостоящие звонки и угрозы терактов, и остается лишь надеяться, что почтовая служба не купила ни одной копии программы. Проблемы с версиями обходятся чудовищно дорого и ведут к потерям производительности и замедлению отладки. Кроме того, эти проблемы заставляют людей воздерживаться от приобретения обновлений или даже от попыток их установки, поскольку они боятся, что после этого что-то обязательно перестанет работать, и часто они оказываются правы.
Управление версиями программ— огромная, мучительная и вовсе :; :|w& привлекательная йроблема,
Объекты .NET
47
Лосих пор Windows игнорировала проблему, \ :„ к,рт ••• связанную с управлением версиями, что вы- включена функциональнуждало разработчиков самим решать эту ность {для управления проблему поэтапно. До .NET у разработчиков версиями. не было стандартизированного способа задать нужную линию поведения при управлении версиями, которую реализовывала бы ОС. Похоже, Microsoft осознала, что эту общую проблему можно решить лишь на уровне ОС, и предоставила в .NET систему управления версиями программ. В декларации каждой сборки есть сведения о ее версии. Они включают номер версии для совместимости — набор из четырех чисел, позволяющий загрузчику CLR реализовать запрошенные клиентом действия по управлению версиями. Номер версии для совместимости состоит из старшего номера версии, младшего номера версии, номеров компоновки и ревизии. Инструменты разработки, которые создают сборку, помещают сведения о версии в декларацию. В Visual Studio.NET они хранятся в атрибутах, которые можно установить в файле проекта Assembly!nfo.vb {рис. 2-11}. Чтобы задать номер версии инструментами командной строки, последним нужны сложные переключатели. Взгляните на номер версии, который вы водит дизассемблер IL (рис. 2-12 внизу). Его также можно увидеть при установке сборки в GAC (рис. 2-8). ' Сведения о версии сборки состоят из следующих ' четырех значений: 1
Старшая версия Младшая версия ' Ревизия 1
' Номер компоновки ' Можно задать все значения или оставить номера 1 компоновки и ревизии по умолчанию с помощью ' * ' 1 как показано ниже: ии Надеюсь, эти изменения будут отвергнуты.
Г л а в а 3
И голоса наперебой — и все понятны мне — Звучат на скорости любой и при любой волне. От крышки люка до котла — единое стремленье. Как зорька ясная, светла их Песнь Благодаренья. Р. Киплинг о взаимодействии и масштабируемости. ("Молитва МакЭндрю», 1894 г.)
Суть проблемы Изначально Web служила для передачи ста- Сначала Web тических страниц с текстом и изображения- использовали оля ми. Запрограммировать сервер для этого просмотра статических было относительно просто — нужно просто страниц, которые было-принять URL, идентифицирующий файл, относительно легко : программировать, взять этот файл с диска сервера и передать этот файл клиенту {рис. 3-1). Даже такая простая архитектура позволяет многое. Например, наш местный кинотеатр имеет небольшой Web-сайт, на котором п могу посмотреть, что идет сегодня (чаще всего «Счастливо, Техас!», в котором двух беглых зэков облапошивают красотки в небольшом техасском городке), что будет скоро, и по ссылкам просмотреть анонсы и отзывы. Они используют Web как бумажную рекламную брошюрку, правда с более привлекательным содержанием, быстрой доставкой и меньшими затратами — словом (ну, может, двумя), более адекватно.
98
Клиентский браузер 1. Пользователь вводит ! : s браузере запрос: «Дай'мне эту страницу». 4. Браузер обрабатывает страницу для отображений г- клиенту;
Глава 3 2. Браузер посылает запрос серверу, Сервер 3-Сераер находит запрошенную .•• страницу я передает ее клиенту,
Рис. 3-1. Сервер передает статические Web-страницы. Этот подход был приемлем в доисторические времена, когда все данные в Web были статическими (отображая только созданное азтором содержание без программной логики и возможности вмешательства со стороны пользователя) и открытыми (доступными всем, кто знал или мог найти адрес). Но со временем потребители стали спрашивать: «Если я могу узнать, какой сегодня фильм, почему я не могу посмотреть текущее состояние своего банковского счета?» Но при статическом подходе это неосуществимо. Банк не может каждый день создавать новую страницу для любого возможного представления каждого счета — страниц окажется слишком много. Вместо этого пользователю нужно ввести некоторую информацию, такую как номер счета, а банковский компьютер должен по запросу создать HTML-страницу, отображающую баланс клиентского счета (рис. 3-2). Такие данные не являются ни статическими, ни открытыми, а это порождает новые проблемы.
Сегодня Wefa-программисты должны уметь динамически создавать НТМЬ-страницы в ответ на данные, полученные • от-пользователя, что порождает новше • проблемы.
Web-серверному приложению, динамически генерирующему страницы для клиента, требуется несколько вещей. Во-первых, ему нужен способ увязки программной логики с запросом страницы. Когда пользователь запрашивает страницу, сервер не может просто извлечь ее с диска — до этого запроса ее просто нет. Вместо этого сервер должен выполнить некий алгоритм для генерации страницы. В при-
Web-сераерным приложениям нужна программная логика для страниц. ,
ASP.NET
99
мере с банком нам, вероятно, потребуется просмотреть банковскую БД и найти текущий баланс пользовательского счета и последние транзакции. Нам бы хотелось реализовать этот алгоритм легко и быстро, с применением уже знакомых языков и инструментов. И хотелось бы, чтобы это работало настолько быстро и эффективно, насколько это возможно в реальной жизни. Клиентский браузер t. Пользователь вводит в браузере запрос: «Дай мне страницу, отображающую транзакции по моему банковскому счету N- 12345». 4, Браузер обрабатывает .:„¥праале№шсеансами. сами. Для пользователя взаимодействие с • Web-сайтом — это не последовательность запросов, но диалог, «сеанс». Он ожидает, что Web-сайт может запоминать, что ему было сказано пару минут назад. Скажем, на сайте электронного магазина он хочет складывать товары в тележку так, чтобы они хранились там до расчета. Чтобы этого добиться, нужен соответствующий код — запрос к отдельной странице не способен поддержать такую функциональность. Это опять же неотъемлемая часть большинства Web-приложений, так что хотелось бы иметь готовую, простую в использовании реализацию. В идеале это должно работать в многосерверной среде и быть устойчивым к сбоям. Короче, нашему серверу нужна исполняющая Нам нужна законченная /-•• е а ' ! ' ; с Р 9 ' предоставляющая готовые решения среадпвйиойа в&шолнения. I проблем, которые возникают при программировании всех Web-серверов. Хотелось бы, чтобы она упрощала программирование, администрирование и развертывание. Нужно чтобы ее можно было распространять хотя бы на несколько, а лучше — на множество серверов. И платить за это много не хочется. А больше нам ничего не нужно?
ASP.NET
101
Архитектура решения В конце 1997 г. Microsoft реализовала отно- : ASP 6blAa жполняющей сительно простую среду периода выполнения средой, которую можно для Web — Active Server Pages (ASP) как часть было легко применять сервера Internet Information Server (IIS), вклю- для простых задач, ченного в Windows NT 4 Option Pack. IIS обслуживает Web-страницы, запрашиваемые пользователем. ASP позволяет программистам реализовывать алгоритмы динамического создания страниц на IIS, состоящих из статического HTML и кода сценариев (рис. 3-3}. Когда пользователь запрашивает ASPстраницу, IIS должен ее найти и активизировать ASP-процессор. ASP-процессор должен прочитать страницу и один к одному скопировать содержащиеся на ней HTML-элементы в выходную страницу. В нашем примере атрибут style устанавливает голубой цвет текста. При этом также интерпретируются элементы сценариев, расположенные между ограничителями . Этот код должен выполнять алгоритм, выдающий в качестве результата HTML-строки, которые ASP-процессор должен скопировать в выходную страницу в те места, где были элементы сценария. Результирующая страница, собранная из статических HTML-элементов и HTML, динамически сгенерированного сценарием, должна быть передана клиенту (рис. 3-4). Для простых задач ASP применять относительно легко, что является признаком качества этой технологии.
The time is: on
Рис. 3-3. Смешение кода и HTML в ASP. По мере расширения Web и увеличения по- ; дер ПОЛНОСТЬЮ требностей пользователей Web-разработчи- переделанная ASP кам потребовались совершенствование двух сохранившая ее лучшие ключевых свойств исполняющей среды: про- концепции. стоты программирования и качества выполнения. ASP.NET и явилось таким усовершенствованием. ASP.NET похожа на оригинальную ASP и большая часть кода может быть переведена на нее практически без изменений. Но внутренняя
102
Глава 3
реализация ASP. NET полностью переделана с тем, чтобы задействовать возможности .NET Framework. Вы обнаружите, что работает она лучше, рушится меньше и в ней проще программировать. И это приятно. 3htlpi//redhiwki;sb/n Если не указано обратное, все пользователи, запрашивающие страницы ASP,NET, имеют к ним доступ.
web.config приложения А Не содержит элемента allow, так что применяется значение по умолчанию, разрешающее доступ для всех.
web.config подкаталога 1 приложения Б Не содержит элементов allow или deny, так что по умолчанию использует значения родителя, разрешающие, доступ любому аутентифици рова н ному пользователю.
web.config приложения S
Это значение переопределяет значение в главном файле. Любому неаутентифицированному пользователю, запрашивающему любую страницу в этом каталоге, доступ запрещен. Любому аутентифицированному пользователю доступ разрешен.
web.config подкаталога 2 приложения Б
Это значение переопределяет родительский каталог. Только члены роли managers могут запрашивать страницы в этом каталоге.
Рис.3-14. Иерархическая природа файлов web.config.
ASP.NET
121
authornatiar alow trace ;essian5tate tittoHandlers add alobalizatior.
Рис.3-15. Утилита редактирования конфигурационных файлов в Visual Studio.NET еще сырая.
Управление состоянием в ASP.NET По умолчанию запросы Web-страниц не заЗапросы, вь*даеаемые висят друг от друга. Если я запрашиваю с одним пользователем, сервера страницу Б, содержимому этой страмогут быть не связаны друг с другом. Иногда ницы неизвестно, просматривал ли я перед это хорошо. этим страницу А. Такой механизм хорошо работает для простых запросов только на чтение, как в примере с кинотеатром, который я приводил в начале главы. Сервер, реализующий такой механизм, легко написать, так как не нужно хранить данные от запроса к запросу. Однако по мере усложнения взаимодействия Но при более развитом в Web такая конструкция перестает удовлетвзаимодействии это ворять потребности пользователей. Мои дейможет быть плохо, , ствия на странице А должны оказывать воздействие на содержимое страницы Б. Скажем, я хочу заказать билеты на самолет прямо на Web-сайте авиакомпании, так как они предоставляют скидки постоянным клиентам. Для меня неприемлемо искать прямой рейс, выписывать его на бумажке, затем искать обратный, выписывать его тоже, а затем вручную вводить
122
Глава 3
номера обоих рейсов на совсем другой странице, чтобы купить билет. Я хочу, чтобы сайт авиакомпании автоматически запоминал, какой прямой рейс я выбрал, когда я выбираю обратный и помнил оба, когда я покупаю билет. Запоминание панных при переходе от одной УУеЬ-гюограммисты ; МЫ к гои зачастую должны управ- Ф°Р 9РУ никогда не было проблемой ЛП АН гь отдельными данны- 9 настольных приложений, рассчитанных ми для многих пользе- на одного пользователя. Программисту нужsate^eO одншременно. но просто хранить входные данные во внутренней памяти программы, не заботясь о том, какому пользователю они принадлежат, так как в каждый отдельный момент программу использует один человек. Но отслеживать пользовательские действия на многих страницах Web-приложения, к которому одновременно обращаются (как вам бы хотелось) многие, гораздо сложнее. Web-программист должен отделять мои данные от данных других пользователей, чтобы не перепутать наши рейсы (правда, если я неожиданно улечу на Гавайи в феврале, это будет здорово!). Мы называем это управлением сеансом, и Web-программисту нужны для этого эффективные и простые средства. Ст ASP NEf позволяет арая ASP обеспечивает простой механизм хранить данные, привз- \ управления сеансами, который поддержан и занные к конкретному расширен в ASP.NET. При каждом обращепользоватймо в объекте Нии к .ASPX-странице ASP,NET создает внутренний объект Session (сеанс). Это набор данных, который живет на сервере и привязан к конкретному активному пользователю. Web-программист может хранить в объекте Session любые интересующие его типы данных. Этот объект автоматически запоминает {помещая уникальный идентификатор в cookie-файл браузера или добавляя его в URL), к какому пользователю относятся данные, так что программисту не нужно писать для этого код. Скажем, когда я передаю форму с выбранным рейсом, программист страницы .ASPX может сохранить сведения о нем в объекте Session. Исполняющая среда .ASPX знает, кто является пользователем (я), так что программа автоматически выдаст мой рейс, а не чей-то еще (рис. 3-16). Объект Session может хранить произвольное число строк для каждого пользователя, но поскольку все они используют серверную па-
123
ASP.NET
мять, советую ограничить объем хранимых данных, связанных с сеансом минимально необходимым. Клиентский браузер 1. Клиент запрашивает , первувэ страницу. Cookie-файл ^ с идентификатором сеанса
Сервер 2. Сервер получает запрос, создает объект Session И сохраняет codkie-фа'йл — на клиенте. 3. Программист сохраняет данные в объекте Session.
4, 'Клиент запрашивает — .вторую страницу, передавая cookie-файл.
5. Сервер выбирает объект Session, на основании cookie-файла.
7, Клиент получает вторую . страницу, информация + на которой соответствует тому, что было на первой.
6, Программист выбирает — данные из обьекта Session. Чудесным образом они являются данными нужного пользователя. Сеансы Данные Данные пользователя пользователя А Б Другие пользователи...
Рис. 3-16. Управление сеансом. Это легко реализуемые и потому популярные ASP-NET предоставляет функции. Каждая ASPX-страница имеет свойпростой API для ство с именем Session, которое дает доступ к установки и получения объекту Session текущего пользователя. Вы сеансовых переменных храните данные в этом объекте в виде строк и соответствующим образом их выбираете. Взгляните на пример кода, который это делает (рис. 3-17). Этот пример вы также найдете на Web-сайте книги. Эти страницы также показаны ниже (рис. 3-18). Естественно, если сервер поддерживал бы ASP.NET автоматически непрерывный сеанс для каждого пользоватеудаляет сеансы после ля, даже если бы тот смотрел всего одну стразаданного интервала ; времени. ницу, ресурсы памяти быстро бы истощились. Механизм сеансов разработан для управления состоянием только активных пользователей, т. е. тех,
124
Глава ;i
кому требуется, чтобы сервер управлял их состоянием. ASP.NET автоматически удаляет объект Session пользователя, сбрасывая его содержимое, если пользователь не проявляет активности в течение некоторого времени. Этот интервал устанавливается в разделе файла web.config (рис. 3-19). Вы можете также сами сбросить сеанс, вызвав метод Session Abandon. 1
Код для сохранения данных сеанса.
Protected Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button"! .Click ' Сохраняем текущую текстовую строку. Session("DemoString") = TextBox1( ).Text ' Перенаправляем пользователя на другую страницу. ResponseC ) .Redirect("WebForm2.aspx") End Sub
'• Код, получающий данные о сеансе. Protected Sub Page_Init(ByVal Sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Init 'CODEGEN: This method call is required by the Web Form Designer. 'Do not modify it using the code editor. InitializeComponent( ) Выбираем строку для сеанса и отображаем как надпись.
Try Label2( ).Text = Session("DemoString").ToString 1
Ссылка на несуществующую строку приведет к исключению. Корректно его обрабатываем.
1
Catch ex As Exception Label2( ).Text = "(session string is empty)"
End Try End Sub Рис. 3-17. Код АЛЯ управления сеансом.
125
ASP. NET
file
|(ji*йгорых пользователь ASP.NET. Но фатальной проблемой для нее должен помнить иденти- является неконтролируемый рост числа сайфикатори пароль, стре- тов. Любой сайт, содержащий хотя бы бит . мительно растет. При критической информации требует реализаэтм возрастает угроза регистуди уном механизма '*>: