Программирование arrow .NET Framework arrow Динамическая компиляция и загрузка кода

Динамическая компиляция и загрузка кода

Оглавление

Прежде чем говорить о динамической компиляции и загрузке кода, нужно ответить на вопрос: зачем нужно динамически выполнять код? Можно привести массу примеров использования, но все, в конечном итоге сводится к одной цели – возможности расширения и изменения функциональности приложения без его перекомпиляции. А теперь посмотрим, чем может помочь .NET Framework в решении этой задачи.

Динамическая загрузка кода

Нередко встречается ситуациякогда, в зависимости от тех или иных факторов, нужно загрузить некоторую сборку(assembly) для последующего выполнения содержащегося вней кода. Пример из жизни – WS-Security, в котором для проверки пароля пользователя используется динамическизагружаемая сборка, идентифицируемая с помощью элемента passwordProvider вфайле web.config. В WS-Security используется самыйраспространенный подход для динамического подключения сборок, которыйзаключается в следующем:

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

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

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

Создать экземпляр класса,находящегося в динамически загружаемой сборке можно несколькими способами. Самыйпростой путь – вызвать у класса Activator метод CreateInstance (или CreateInstanceFrom).При этом будет неявно загружена сборка, содержащая искомый класс (если этасборка не была загружена ранее). Можно выбрать более сложный путь – загрузитьсборку (вызвав один из соответствующих статических методов, например, Assembly.Load), получить нужный тип(вызвав метод Assembly.GetType,с названием класса в качестве параметра), получить у типа информацию оконструкторе (вызвав метод Type.GetConstructor)и, наконец, создать экземпляр класса с помощью метода ConstructorInfo.Invoke. Можно также воспользоваться методами CreateInstance классов Assembly или AppDomain (они вызывают метод Activator.CreateInstance). О том, как загрузить сборку, и какаяинформация для этого необходима, подробно описано в MSDN.

Динамическая загрузка доменовприложений (application domains) может понадобиться по двум причинам – дляобеспечения большей безопасности (изолированности загруженного кода) и длявозможности выгрузки динамически загруженных сборок (в .NET Framework нет возможности выгрузитьсборку – только домен приложения). Однако за изолированность доменов приходитсяплатить тем, что вызовы между границами доменов происходят с помощью Remoting. Подробнее о доменах приложений вообще и, вчастности, об их изолированности можно прочитать в MSDN.

В .NET Framework 2.0 появились новые методы, Assembly.ReflectionOnlyLoad и Assembly.ReflectionOnlyLoadFrom, позволяющие загрузить сборку только для получения информации о ней. Вызов этогометода позволяет считывать информацию о сборке, не загружая ее для выполнения.Также добавлен аналогичный метод для типа - Type.ReflectionOnlyGetType.Загруженные таким образом сборки по-прежнему нельзя выгрузить отдельно. Но,помимо более высокой скорости загрузки, эти методы позволяют обойти некоторыезапреты, имеющие смысл при выполнении кода, но мешающие получению информации осборке. К примеру, можно просмотреть сборку, скомпилированную под другойпроцессор, обойти CAS Policy, не выполнять конструктор модуля. Снятие подобныхограничений будет особенно полезно при написании приложений предназначенныхтолько для исследования сборок, таких как .NET Reflector. Очевидно, что дляподобных приложений невозможность получить информацию о 64-битной сборке намашине с 32-битным процессором была бы, по меньшей мере, неприятной.


 
« Предыдущая статья   Следующая статья »


  • .NET Framework, Оптимизация сериализации в .NET
    Приводятся код и методы, позволяющие разработчикам оптимизировать сериализацию данных....
  • .NET Framework, Плавающая точка в .NET - часть 1: принципы и форматы
    Данная статья представит основные принципы арифметических операций с плавающей точкой: числовые форматы, точности и достоверность, погрешности округления. Также в статью включено обсуждение типов плавающей запятой в .NET....
  • .NET Framework, JIT-оптимизации
    Компилятор .NET Just-In-Time Compiler (JIT) считается многими одним из основных преимуществ производительности CLR по сравнению с JVM и другими управляемыми средами, которые используют двоичный код, скомпилированный компилятором JIT. ...
  • .NET Framework, Инъекции CLR: замена методов во время выполнения
    Многие из нас, наверняка, были заинтересованы в том, как работает универсальный язык CLR. Одной из наиболее интересных вещей является динамический компилятор JIT (Just In Time Compiler). Мы рассмотрим то, как JIT компилирует MSIL и создадим утилиту, которая позволяет программным образом заменить любой метод (JIT) другим во время выполнения. Мы также создадим отладочную утилиту, которая прехватывает JIT-вызовы и выводит в консоль информацию о диагноcnbrt....
  • .NET Framework, Оптимизация запуска приложений .NET
    Ждать, пока приложение запустится, неприятно для многих пользователей, поэтому ускорение запуска приложений клиентов может значительно улучшить первое впечатление от вашей работы. И так как скорость запуска имеет значение, следует знать факторы, которые на нее влияют, чтобы избежать распространенных ошибок....
  • .NET Framework, Создание компилятора языка для .NET Framework
    Эксперты по компиляторам являются знаменитостями в компьютерном мире. Я видел, как Андерс Хейльсберг (Anders Hejlsberg) представлял презентацию на конференции разработчиков Professional Developers Conference и когда он сошел со сцены, его встретила целая орда мужчин и женщин, просящих поставить автограф на книгу, или сняться на фотографии вместе с ними. Люди, посвящающие свое время изучению и пониманию всех тонкостей лямбда-выражений, систем типов и языков сборки, кажутся своего рода носителями ...
  • .NET Framework, Маршалинг данных между управляемым и неуправляемым кодом
    Посмотрим правде в глаза: нет в мире совершенства. Мало кто при разработке использует только управляемый код. А между тем, тяжким грузом лежат устаревшие неуправляемые приложения, с которыми приходится мириться. Есть ли способ интегрировать проекты, в которых задействован как управляемый, так и неуправляемый код? Какой вид принимает этот способ: вызов неуправляемого кода из управляемого приложения или вызов управляемого кода из неуправляемого приложения?...
  • .NET Framework, IronPython как движок для макросов в .NET приложениях
    Подозреваю, многие из вас задумывались — как можно в .NET приложение добавить поддержку макросов — чтобы можно было расширять возможности программы без ее перекомпиляции и предоставить сторонним разработчикам возможность легко и просто получить доступ к API вашего приложения? В статье рассмотрено, как в качестве основы для выполнения макросов использовать IronPython — реализацию языка Python на платформе .NET....