Вавилонское столпотворение в .NET проекте
В крупных проектах зачастую возникает необходимость (ну или по крайней мере сильное желание) писать код на разных языках. Например, большая часть кода написана на C, часть была быстро накидана в виде прототипа на Python, а кусок для работы с базой знаний был вообще сделан на каком-то декларативном языке. Объединить все это вместе раньше было довольно проблематично — разные форматы данных, абсолютно разная организация памяти, и многие другие причины мешали с легкостью составлять вместе «кирпичики» кода на разных языках.
Благодаря CLS, принятой для языков платформы .NET это делается очень легко и непринужденно. Сейчас я покажу это на простом примере. Рассказ для наглядности будет снабжен максимально разумным числом картинок.
Допустим нам надо создать маленькую программку, запускающую Internet Explorer и направляющую его на нужную нам страницу. Конечно проще всего сформировать правильный URL и отдать его на растерзание функции типа ShellExecute. Но мы не ищем легких путей, поэтому я предлагаю усложнить задачу. Управлять открытым IE мы будем как объектом COM. Зачем так усложнять жизнь я расскажу ближе к концу, а пока что просто решим поставленную задачу.
Для управления COM-объектами замечательно подходит язык Boo, благодаря заложенной в него архитектуре динамической (утиной) типизации. Собственно таким и будет наше тренировочное приложение: класс-обертка для Internet Explorer’a, написанный на Boo и управляющая программа на C#.
Для небольших проектов (как в данном случае) я рекомендую использовать IDE SharpDevelop (www.icsharpcode.com), помимо полной бесплатности он еще обладает замечательным биндингом для Boo.
Начнем работу с создание управляющего приложения, выберем в меню File — New Solution, тип решения установим в C# Windows Application.
Теперь добавим в решение проект для класса на Boo. Для этого в окне инспектора проектов щелкнем правой кнопкой мышки на нашем решении и выберем Add — New Project.
Тип проекта выберем Boo — Class Library.
Теперь необходимо добавить ссылку на «дочерний» проект в главный проект на C#. Для этого из контекстного меню C# проекта выберем пункт Add reference.
В появившемся окне, на второй закладке, отвечающей за референсы на проекты выберем наш Boo-проект и нажмем Select.
Вуаля! Все работает. Это подтверждается добавлением BooAddIn в список References главного проекта и работоспособностью IntelliSence в главном проекте.
Теперь настала пора написать немного кода :-).
Для начала — вспомогательный класс прослойка.
namespace BooAddIn import System class IEWrapper: """Wrap IE for our uses""" ie as duck def constructor(): """Create a wrapper""" ie = System.Type.GetTypeFromProgID("InternetExplorer.Application")() def NavigateTo(url as string): """Show IE Window and navigate to URL""" ie.Visible = true ie.Navigate2(url)Мы создали класс, содержащий одно поле (переменную-хранилище COM-объекта) и 2 метода. Первый — конструктор, создает экземпляр COM объекта и «привязывает» его к полю класса ie. Поскольку член класса ie объявлен как тип duck, нам нет необходимости выполнять какие-либо действия по декларированию типа и т.п. Тут на полную будет работать динамическая типизация.
Второй метод — получает 1 строковой параметр, показывает окно IE и «отправляет» его по нужному нам адресу.
Создать «основную программу» еще легче — просто в визуальном дизайнере форм размещаем одно текстовое поле и одну кнопку. Немного правим конструктор и обработчик нажатия кнопки. Вот что должно получиться.
using System; using System.Windows.Forms; using BooAddIn; namespace MainApp { public partial class MainForm : Form { IEWrapper iew; public MainForm() { InitializeComponent(); iew = new IEWrapper(); } void GoButtonClick(object sender, EventArgs e) { iew.NavigateTo(urlBox.Text); } } }Если все сделано правильно, то после нажатия на кнопку Run мы получим искомую запускалку.
Последнее что стоит рассказать — зачем же нам понадобилось мучиться с COM. Очень просто, управляя IE как COM-объектом, мы можем добиться от него куда большего чем просто запуска и открытия страницы.
Например, после загрузки документа мы можем получить все заголовки 2 уровня и что-то с ними сделать.
h2s = ie.Document.getElementsByTagName("h2") for hdr in h2s: print(hdr)
Это открывает очень богатые возможности, например, для автоматического тестирования Web-сайтов прямо браузером (hint: Boo отлично интегрируется в NUnit).
Вот и все на сегодня, я был бы очень признателен за отзывы, стоит ли продолжать тему нестандартных языков .NET.
20 коментарів
Підписатись на коментаріВідписатись від коментарів Коментарі можуть залишати тільки користувачі з підтвердженими акаунтами.