Microsoft .NET Framework FAQ

ОГЛАВЛЕНИЕ

Microsoft .NET Framework - это платформа для создания, развертывания и запуска Web-сервисов и приложений. Она предоставляет высокопроизводительную, основанную на стандартах, многоязыковую среду, которая позволяет интегрировать существующие приложения с приложениями и сервисами следующего поколения, а также решать задачи развертывания и использования интернет-приложений. .NET Framework состоит из трех основных частей - общеязыковой среды выполнения (common language runtime), иерархического множества унифицированных библиотек классов и компонентную версию ASP, называемую ASP.NET.

Технические вопросы о среде выполнения

Терминология

Что такое общеязыковая среда выполнения - Common Language Runtime (CLR)?

Общеязыковая среда выполнения - это ядро для выполнения приложений в .NET Framework
Она предоставляет набор сервисов, включая следующие:

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

Что такое общая система типов(CTS)?

Общая система типов - это мощная система типов, встроенная в CLR, которая поддерживает типы и операции, существующие в большинстве языков программирования.

Что такое общеязыковая спецификация - Common Language Specification (CLS)?

Common Language Specification - это набор конструкций и ограничений, которые являются руководством для создателей библиотек и компиляторов. Она позволяет библиотекам быть полностью использованными из любого языка программирования, поддерживающего CLS, и позволяет этим языкам интегрироваться друг с другом. CLS является подмножеством общей системы типов. CLS очень важна для разработчиков, которые пишут код, который будет использоваться другими разработчиками. Когда разработчик проектирует публично доступное API, используя правила CLS, то это API можно будет легко использовать из любого языка программирования, управляемого CLR.

Что такое промежуточный язык Microsoft - Microsoft Intermediate Language (MSIL)?

MSIL - это независимый от процессора набор инструкций, в который компилируются программы в .NET Framework. Он содержит инструкции для загрузки, хранения, инициализации и вызова методов объектов.

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

Перед выполнением, MSIL преобразуется в машинный код. Он не интерпретируется.

Что такое управляемый код (managed code) и управляемые данные (managed data)?

Управляемый код - это код, который работает в среде CLR. Чтобы выполняться в среде, код должен предоставить определенный уровень информации (метаданных) для среды выполнения. Код C#, Visual Basic .NET, и JScript .NET является управляемым по умолчанию. Код Visual Studio .NET C++ не является управляемым по умолчанию, но компилятор может создавать управляемый код, для этого нужно указать аргумент в командной строке(/CLR).

Близким понятием к управляемому коду является управляемые данные - данные, которые создаются и уничтожаются сборщиком мусора CLR. Данные C#, Visual Basic и JScript .NET являются управляемыми по умолчанию. Но данные C# могут быть помечены как неуправляемые, используя специальное ключевое слово. Данные Visual Studio .NET C++ являются неуправляемыми по умолчанию (даже при использовании флага /CLR ), но при использовании Managed Extensions for C++, класс может быть помечен как управляемый, используя ключевое слово __gc. Как можно понять из имени, это означает, что память для экземпляров данного объекта должна управляться сборщиком мусора. Тогда класс становится полноценным участником сообщества .NET Framework, с теми преимуществами и ограничениями, которые она дает. Например, преимуществом является корректное взаимодействие с классами, написанными на других языках программирования, а ограничением явялется возможность наследования только от одного базового класса.


 

Сборки

Что такое сборка?

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

Самоописываемая природа сборок позволяет реализовать безболезненную инсталляцию и развертывание, через XCOPY.

Что такое приватные сборки и совместно используемые сборки?

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

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

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

Для локально устанавливаемых приложений, совместно используемые сборки обычно устанавливаются в глобальный кэш сборок. Ключевой особенностью системы управления версиями .NET Framework является то, что загруженный код не влияет на выполнение локально установленных приложений. Загруженный (с Интернета или Интранета) код размещается в специальный кэш загрузки и не доступен глобально на машине, даже если определенные из компонент помечены как совместно используемые сборки.

Классы, которые включены в состав .NET Framework являются совместно используемыми сборками.

Если я хочу создать совместно используемую сборку, требует ли это работы с подписями и парами ключей?

Создание совместно используемой сборки включает работу с ключами шифрации. Для построения сборки обязательно необходим только публичный ключ. Компиляторы, входящие в .NET Framework, имеют набор аргументов в командной строке, которые позволяют указать публичный ключ при создании сборки. Обычно копию ключа хранят вместе с исходниками и указывают, что при сборке использовать данный ключ. Перед передачей сборки, она должна быть полностью подписана, с соответствующим приватным ключом. Это делается с использованием утилиты SN.EXE, входящей в состав SDK.

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

В чем отличие между пространством имен и именем сборки?

Пространство имен - это логическая схема именования типов, в которой простому имени типа, например, МойТип, предшествует разделенное точками иерархическое имя. Такая схема именования находится полностью под контролем разработчика. Например, по имени типов МояКомпания.ФайловыйДоступ.А и МояКомпания.ФайловыйДоступ.В можно ожидать, что их функциональность имеет отношение к работе с файлами. .NET Framework использует иерархическую схему именования типов для объединения типов в логические категории с общей функциональностью. Средства разработки позволяют удобно просматривать типы, ссылаться на них и использовать в коде. Концепция пространства имен не имеет прямого отношения к сборке. Одна сборка может содержать типы, имена которых начинаются в разных пространствах имен, и одно пространство имен может быть реализовано в нескольких сборках. В .NET Framework пространство имен является соглашением по именовании в процессе разработки, в то время как сборка устанавливает область действия имени для типа в период выполнения.


 

Развертывание и изоляция приложений

Какие существуют варианты развертывания моего .NET приложения?

.NET Framework упрощает развертывание, делая возможным установку системы без побочных эффектов и развертывать приложение, используя утилиту XCOPY. Поскольку все запросы обрабатываются сначала в приватной директории приложения, то для запуска приложения необходимо просто скопировать файлы приложения на диск. Никакой регистрации не требуется.
Такой сценарий применим для Web-приложений, Web-сервисов и клиентских приложений. Однако, сценарий с использованием XCOPY, не всегда подходит при распространении приложения. Например, когда приложение состоит из небольшой части приватного кода, и использует большое количество совместно используемых сборок, или когда приложение не всегда полностью установлено локально (например, определенные части приложения скачиваются и загружаются по требованию). Для таких ситуаций, в .NET Framework предусмотрены сервисы для скачивания кода и интеграция с Windows Installer. Скачивание кода, которое поддерживается .NET Framework, предоставляет ряд дополнительных преимуществ, таких, как поддержка скачивания по частям, безопасности доступа кода (без Authenticode), изоляция приложений (код, скаченный в рамках одного приложения, не оказывает влияние на другое). Windows Installer представляет собой еще один мощный механизм развертывания, доступный для .NET приложений. Все возможности Windows Installer, включая публикацию, размещение рекламных заставок, восстановление приложений, доступны для .NET приложений в Windows Installer 2.0.

Я написал сборку, которую хочу использовать в нескольких приложениях. Где я должен разместить ее?

Сборки, которые будут использоваться несколькими приложениями, размещаются в глобальном кэше сборок. В версиях PreRelease и Beta, используйте переключатель /i в утилите GACUtil из SDK, чтобы установить сборку в кэш:

gacutil /i myDll.dll
Windows Installer 2.0, входящий в состав Windows XP и Visual Studio .NET будет иметь возможность устанавливать сборки в глобальный кэш сборок.

Как я могу посмотреть, какие сборки установлены в глобальном кэше сборок?

В .NET Framework входит расширение оболочки Windows для работы просмотра кэша сборок. Перейдите в директорию % windir%assembly, используя проводник, чтобы запустить программу просмотра.

Что такое домен приложения?

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

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


 

Сборка мусора

Что такое сборка мусора?

Сборка мусора - это механизм, позволяющий компьютеру определить, когда объект более недоступен. Тогда он автоматически освобождает память, используемую этим объектом (вызывая функцию finalizer, реализованную пользователем). Некоторые сборщики мусора (в т.ч. используемый в .NET), "сжимают" память, уменьшая количество ресурсов, используемых вашей программой.

Как наличие сборщика мусора влияет на написание кода?

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

Могу я не использовать память, контролируемую сборщиком мусора?

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

В CLR также поддерживается понятие Тип-Значение (ValueType) - понятие, подобное классам, за исключением того, что такие значения размещаются на стеке (а не в куче), поэтому автоматически удаляются, когда завершается выполнение процедуры, в которой они определены. Таким образом реализуются структуры в C#.

Managed Extensions для C++ позволяют вам указать, где создавать объекты. Если вы объявляете управляемый класс, указывая ключевое слово __gc, то он будет размещен в куче памяти, контролируемой сборщиком мусора. Если вы не использовали ключевое слово __gc, то поведение будет аналогично обычным объектам C++, которые создаются в куче памяти C++ и освобождаются, используя метод "free".


 

Удаленные вызовы

Как взаимодействия внутри процесса и между процессами работают в CLR?

Есть два аспекта взаимодействия внутри процесса: между контекстами внутри одного домена приложения и между разными доменами приложений. Между контекстами внутри одного домена приложения, используются прокси. Нет маршаллинга и сериализации. Когда взаимодействие происходит между доменами приложений, то происходит маршаллинг и сериализация, используя бинарный протокол среды выполнения.
Межпроцессные взаимодействия используют блочный (pluggable) канал и протокол формата, каждый для определенных целей.

Если разработчик указывает конечную точку, с использованием утилиты soapsuds.exe для создания прокси, то HTTP канал и формат SOAP используются по умолчанию.
Если разработчик делает вызов в управляемом коде, то необходимо точно указать, какой канал и какой формат использовать. Это может быть определено административно, через файлы конфигурации, либо через вызовы API для загрузки определенных каналов. Есть следующие варианты:
HTTP канал с форматом SOAP (HTTP работает хорошо в Интернет, или в любом месте, где трафик должен идти через системы защиты)

TCP канал с бинарным форматом (TCP - более производительный вариант для локальных сетей)

Когда происходит переключение между управляемым и неуправляемым кодом, то используется инфраструктура COM/DCOM. В начальных вариантах CLR, он же использовался для вызова сервисных компонент (компонент, которые используют COM+ сервисы). В окончательном варианте, должна быть реализована возможность настраивать вызов любой удаленной компоненты.

Сборка мусора для арспределенных объектов, носит название "leased based lifetime." - договорной жизненный цикл. Каждый объект имеет оговоренное время, и когда это время истекает, то объект отсоединяется от инфраструктуры CLR. Объекты имеют по умолчанию время обновления - срок обновляется, когда происходит удачный вызов от клиента к объекту. Кроме того, клиент может непосредственно обновить договор.



Совместимость

Могу я использовать COM-объекты из программы в .NET Framework?

Да. Любая COM-компонента, которую вы создаете сегодня, может быть использована из управляемого кода, и в общем случае адаптация происходит автоматически.
COM-компоненты доступны из .NET Framework через обертку вызовов среды выполнения - runtime callable wrapper (RCW). Эта обертка оборачивает интерфейсы вызываемых COM-компонент в интерфейсы, совместимые с .NET Framework. Для OLE-интерфейсов, обертка может создаваться автоматически из библиотеки типов. Для других интерфейсов, разработчики могут написать свою обертку и вручную связать типы компоненты с типами, совместимыми с .NET Framework.

Могут компоненты .NET Framework использоваться из COM-программ?

Да. Управляемые типы, которые вы создаете, могут быть доступны из COM и в общем случае все происходит автоматически. Некоторые возможности управляемого окружения не доступны из COM. К примеру, статические методы и параметризованные конструкторы не могут быть использованы из COM. В общем случае, бьыло бы хорошо заранее решить, кто будет пользователем данного типа. Если тип будет использоваться из COM, то вы можете быть ограничены в использовании некоторых возможностей.

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

Компоненты .NET Framework доступны из COM, используя обертку вызовов COM - COM callable wrapper (CCW). Она подобна RCW (см. предыдущий вопрос), но работает в противоположном направлении. И также, если средства разработки .NET Framework не могут автоматически создать обертку, или автоматическое поведение не соответствует тому, что вы ожидали, то вы можете создать обертку вручуню.

Можно использовать Win32 API из программы в .NET Framework?

Да. Используя платформный вызов, программы .NET Framework могут получить доступ к базовым библиотекам, указывая точки входа в DLL.

Вот пример вызова из C# функции MessageBox :

using System;
using System.Runtime.InteropServices;

class MainApp
{
[DllImport("user32.dll", EntryPoint="MessageBox")]
public static extern int MessageBox(int hWnd, String strMessage, String strCaption, uint uiType);

public static void Main()
{
MessageBox( 0, "Hello, this is PInvoke in operation!", ".NET", 0 );
}
}


 

Безопасность

Как сделать, чтобы мой код взаимодействовал с системой безопасности?

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

Почему мой код получает исключение от системы безопасности, когда я запускаю ее с сетевого диска?

Используемая по умолчанию политика безопасности дает ограниченный набор прав для кода, который запускается из локальной интранет зоны. Эта зона определяется установками безопасности Internet Explorer, и используется, чтобы определить локальную сеть в предприятии. Поскольку файлы, имеющие UNC-вид, или находящиеся на сетевом диске (используя команду NET USE), передаются через локальную сеть, они тоже считаются в локальной зоне интранет.

Значения по умолчанию исходят из ситуации небезопасного интранета. Если ваш интранет безопасен, то вы можете изменить политику безопасности (используя утилиту конфигурации .NET Framework или утилиту CASPol ), чтобы предоставить больше прав для локального интранета, или его части (например, для определенных разделяемых дисков).

Как запустить код, если политика безопасности его остановила?

Исключения по безопасности случаются, когда код пытается выполнить операции, на которые у него нет прав. Права даются на основании того, что известно о коде, в основном по его месторасположению. Например, код, загружаемый из Интернета получает значительно меньше прав, чем код, установленный локально, поскольку он потенциально более опасен. Так, чтобы позволить коду работать, когда система безопасности вызвала исключение, вы должны увеличить права, предоставленные коду. Самый простой путь - переместить приложение в более доверяемое место (например, в локальную файловую систему). Но это не будет работать во всех случаях (хорошим примером являются web-приложения или интранет-приложения в корпоративной сети). Поэтому, вместо изменения месторасположения кода, вы можете изменить установки политики безопасности, чтобы дать текущему месторасположению больше прав. Это делается с помощью утилиты конфигурации .NET Framework Configuration или утилиты управления правами доступа (caspol.exe). Если вы разработчик кода, то вы можете подписать код цифровой подписью и затем модифицировать политику безопасности, чтобы дать больше прав для кода с данной подписью. Выполняя любое из этих действий, не забывайте, что код имел меньше прав, поскольку он поступил не из источника, которому полностью доверяют, поэтому, прежде чем вы переместите код на локальную машину или измените политику безопасности, вы дложны быть уверены, что данный код не выполняет никаких вредных действий.

Как администрировать политику безопасности на компьютере? В предприятии?

.NET Framework включает утилиту конфигурации .NET Framework Configuration, модуль управления для консоли MMC (mscorcfg.msc), чтобы конфигурировать определенные элементы политики безопасности. Модуль управления для консоли MMC не только поддерживает администрирование политики безопасности на локальной машине, но и создает пакеты, совместимые с System Management Server и групповой политикой безопасности (Group Policy). Утилита командной строки, CASPol.exe, может также быть использована для управления политикой безопасности на машине. Чтобы запустить любую из этих утилит, перейдите в директорию установки .NET Framework (находится в %windir%Microsoft.NetFrameworkv1.0.2914.16) и наберите mscorcfg.msc или caspol.exe.

Как evidence-based политика безопасности работает с политикой безопасности Windows 2000 ?

Evidence-based политика безопасности (которая авторизует код) работает вместе с политикой безопасности Windows 2000 (которая основана на индентификаторе, под которым осуществлен вход). Например, чтобы получить доступ к файлу, управляемый код должен иметь оба права - и право доступа кода к файлу и должен быть запущен под пользователем, который имеет права на файл на уровне NTFS. Управляемые библиотеки, включенные в состав .NET Framework также предоставляют классам безопасность, основанную на ролях. Это позволяет приложению работать с авторизацией Windows и пользовательскими группами.