- •1. Язык программирования c# 3
- •2. Базовые элементы .Net Framework 67
- •3. ТЕхнология .Net Remoting 144
- •Введение
- •1. Язык программирования c#
- •1.1. Платформа .Net – обзор архитектуры
- •1.2. Язык c# - общие концепции синтаксиса
- •1.3. Система типов языка c#
- •1.4. Преобразования типов
- •1.5. Идентификаторы, ключевые слова и литералы
- •1.6. Объявление переменных, полей и констант
- •1.7. Выражения и операции
- •1.8. Операторы языка c#
- •1.9. Объявление и вызов методов
- •1.10. Массивы в c#
- •1.11. Работа с символами и строками в c#
- •1.12. Синтаксис объявления класса, Поля и методы класса
- •1.13. Свойства и индексаторы
- •1.14. Конструкторы класса и Жизненный цикл объекта
- •1.15. Наследование классов
- •1.16. Перегрузка операЦий
- •1.17. Делегаты
- •1.18. События
- •1.19. Интерфейсы
- •1.20. Структуры и перечисления
- •1.21. Пространства имен
- •1.22. Генерация и обработка исключительных ситуаций
- •1.23. Нововведения в языке c# 2.0
- •1.24. Обобщенные типы (generics)
- •2. Базовые элементы .Net Framework
- •2.1. Метаданные и механизм отражения
- •2.2. Пользовательские и встроенные атрибуты
- •2.3. Пространство имен system.Collections
- •2.4. Работа с файлами и директориями
- •2.5. Использование потоков данных
- •2.6. Сериализация
- •2.7. Сериализация объектов в нестандартном формате
- •2.8. Введение в xml
- •2.9. Работа с xml-документами в .Net framework
- •2.10. МНогопоточное программирование
- •2.11. Синхронизация потоков
- •2.12. Асинхронный вызов методов
- •2.13. Состав и взаимодействие сборок
- •2.14. Конфигурирование сборок
- •3. ТЕхнология .Net Remoting
- •3.1. Домены приложений
- •3.2. Архитектура .Net Remoting
- •3.3. Активация удаленных объектов и их время жизни
- •3.4. Программная настройка Remoting
- •3.5. Удаленные Объекты с клиентской активацией
- •3.6. Настройка Remoting при помощи конфигурационных файлов
- •3.7. Хостинг распределенных приложений
- •3.8. Объекты-сообщения
- •3.9. Пользовательские канальные приемники
- •4.1. Архитектура ado.Net
- •4.2. Учебная база cd Rent
- •4.3. Соединение с базой данных
- •4.4. Выполнение команд и запросов к базе данных
- •4.5. Чтение данных и объект DataReader
- •4.6. Параметризированные запросы
- •4.7. Рассоединенный набор данных
- •4.8. Заполнение Рассоединенного набора данных
- •4.9. Объект класса DataColumn – колонка таблицы
- •4.10. Объекты класса DataRow – строки таблицы
- •4.11. Работа с объектом класса DataTable
- •4.12. DataSet и схема рассоединенного набора данных
- •4.13. Типизированные DataSet
- •4.14. Поиск и фильтрация данных в DataSet
- •4.15. Класс DataView
- •4.16. СиНхронизация набора данных и базы
- •5.1. Архитектура и общие концепции asp.Net
- •5.2. Пример aspx-страницы. Структура страницы
- •5.3. Директивы страницы
- •5.4. Класс System.Web.Ui.Page. События страницы
- •5.5. Серверные элементы управления
- •5.6. Элементы управления Web Controls
- •5.7. Проверочные элементы управления
- •5.8. Списковые элементы управления
- •5.9. Связывание данных
- •5.11. Управление состояниями в web-приложениях
- •5.12. Кэширование
- •5.13. Безопасность в web-приложениях
- •5.14. Создание пользовательских элементов управления
- •Литература
2.14. Конфигурирование сборок
Необходимость конфигурирования сборок обычно возникает при развертывании приложений. Платформа .NET предлагает стандартизированный подход к конфигурированию, основанный на использовании конфигурационных XML-файлов. Специальное пространство имен System.Configuration отвечает за работу с файлами конфигураций.
Рассмотрим общую схему файла конфигурации. Корневым элементом файла всегда является элемент configuration. Некоторые подчиненные элементы описаны далее:
startup – совокупность параметров запуска приложения;
runtime – параметры времени выполнения. Они регулируют способ загрузки сборок и сборку мусора;
system.runtime.remoting – параметры конфигурирования, необходимые для настройки механизма .NET Remoting;
system.diagnostics – совокупность диагностических параметров, которые задает способ отладки приложений, перенаправляют сообщения отладки и т. д.;
system.web – параметры конфигурации приложений ASP.NET.
Платформа .NET Framework имеет один файл конфигурации компьютера с параметрами, относящимися к системе в целом. Этот файл называется machine.config. Любая сборка может иметь собственный конфигурационный файл. Он должен носить имя файла сборки (с расширением) с добавленным окончанием .config и располагаться в одном каталоге со сборкой. Таким образом, файл конфигурации для main.exe должен называться main.exe.config. В случае web-приложений файл конфигурации всегда называется web.config.
Разберем на примерах некоторые возможности конфигурирования. Рассмотрим подробнее структуру секции runtime:
<configuration>
<runtime>
<developmenMode>
<assemblyBinding>
<probing>
<publisherPolicy>
<qualifyAssembly>
<dependentAssembly>
<assemblyIdentity>
<bindingRedirect>
<codeBase>
<publisherPolicy>
<gcConcurrent>
<developmenMode>
Прототип тэга:
<developmenMode developerInstallation = "true" | "false"/>
Если параметр тэга равен "true", то среда исполнения помимо обычных каталогов пытается искать сборки в каталогах, указанных в переменной среды окружения DEVPATH.
<assemblyBinding>
Тэг служит для объединения группы вложенных элементов
<probing>
Прототип тэга:
<probing privatePath = "paths"/>
Тэг используется для указания подкаталогов, в которых производится поиск локальных сборок приложения. Например, пусть основное приложение AppMain.exe размещено в каталоге C:\Test, и оно использует сборку Add1.dll из каталога C:\Test\bin и сборку Add2.dll из каталога C:\Test\bin\bin2. Тогда для корректного запуска основного приложения файл AppMain.exe.config должен иметь следующий вид:
<configuration>
<runtime>
<assemblyBinding>
<probing privatePath = "bin;bin\bin2"/>
</assemblyBinding>
</runtime>
</configuration>
<publisherPolicy>
Прототип тэга:
<publisherPolicy apply = "yes" | "no"/>
Пусть приложение использует некую стороннюю библиотеку. Если в тэге <publisherPolicy> определен параметр "yes" (по умолчанию), то при установке новой версии библиотеки, приложение автоматически будет использовать эту новую версию. В случае параметра "no" приложение откажется работать с новой версией.
<qualifyAssembly>
Прототип тэга:
<qualifyAssembly partialName="PartName" fullName="FullName"/>
Этот тэг позволяет ассоциировать сокращенное имя сборки с полным строгим именем для удобства использования в программе. Рассмотрим следующий пример:
<configuration>
<runtime>
<assemblyBinding>
<qualifyAssembly
partialName = "Strong"
fullName = "Strong, version=1.2.0.0,
culture=neutral,
publicKeyToken=1234567812345678"/>
</assemblyBinding>
</runtime>
</configuration>
Конфигурационный файл данного примера позволит везде в программе вместо длинного строго имени использовать короткий псевдоним Strong.
<dependentAssembly>
Этот тэг позволяет настроить загрузку персонально для каждой сборки, связанной с основным приложением. Он сам является пустым и объединяет элементы <assemblyIdentity>, <bindingRedirect>, <codeBase>, <publisherPolicy>. Элемент должен быть указан для каждой сборки, политику загрузки которой мы собираемся настраивать.
<assemblyIdentity>
Прототип тэга:
<assemblyIdentity
name = "assembly Name" publicKeyToken = "public key token"
culture = "assembly culture"/>
Тэг идентифицирует сборку
<bindingRedirect>
Прототип тэга:
<bindingRedirect
old version = "old assembly version"
new version = "new assembly version"/>
Тэг позволяет подменить версию сборки, которая будет загружаться приложением. Рассмотрим пример:
<configuration>
<runtime>
<assemblyBinding>
<dependentAssembly>
<assemblyIdentity name = "myAssembly"
publicKeyToken="32ab4ba45e0a69a1"
culture = "neutral"/>
<bindingRedirect oldVersion = "1.0.0.0"
newVersion = "2.0.0.0"/>
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>
Теперь, если основное приложение запросит сборку myAssembly версии 1.0.0.0, то, ничего не зная об этом, получит сборку версии 2.0.0.0.
<codeBase>
Прототип тэга:
<codeBase version="assembly version" href="URL of assembly"/>
Этот тэг позволяет задать произвольное местоположение зависимой сборки. Причем, в качестве параметра href может быть указан сетевой адрес. Продемонстрируем это на примере:
<configuration>
<runtime>
<assemblyBinding>
<dependentAssembly>
<assemblyIdentity name = "myAssembly"
publicKeyToken = "32ab4ba45e0a69a1"
culture = "neutral"/>
<codeBase version = "1.0.0.0"
href = "http://localhost/one/Strong.dll"/>
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>
Этот конфигурационный файл предписывает загружать среде исполнения сборку Strong из Интернета по адресу http://localhost/one/Strong.dll.
<gcConcurrent>
Прототип тэга:
<gcConcurrent enabled = "true" | "false"/>
Если параметр enabled установлен в true, то «сборка мусора» происходит в параллельном потоке по отношению к основному приложению. Это поведение по умолчанию.
Рассмотрим задачу размещения собственных данных в конфигурационном файле сборки. В простейшем варианте для этого используется секция appSettings. Данная секция может содержать следующие элементы:
<add key = "name" value = "the value"/> – добавляет новый ключ и значение в коллекцию конфигурационных элементов;
<remove key = "name"/> – удаляет существующий ключ и значение из коллекции конфигурационных элементов;
<clear/> – очищает коллекцию конфигурационных элементов.
Для работы с данными секции appSettings используется класс ConfigurationSettings из пространства имен Sistem.Configuration. Статическое свойство AppSettings представляет собой коллекцию, позволяющую получить строковое значение конфигурационного элемента по ключу.
Пусть имеется следующее консольное приложение main.exe:
using System;
using System.Configuration;
class MainClass {
static void Main() {
string v1 = ConfigurationSettings.AppSettings["key1"];
string v2 = ConfigurationSettings.AppSettings["key2"];
Console.WriteLine(v1);
Console.WriteLine(v2);
Console.ReadLine();
}
}
Создадим для этого приложения конфигурационный файл main.exe.config:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<appSettings>
<add key="key1" value="Alex" />
<add key="key2" value="Volosevich" />
</appSettings>
</configuration>
Результат выполнения main.exe:
Alex
Volosevich
Все секции конфигурационного файла разбираются специальными классами-обработчиками (section handlers). Такой класс реализует интерфейс System.Configuration.IConfigurationSectionHandler. В составе .NET Framework имеется несколько готовых классов-обработчиков: NameValueSectionHandler, IgnoreSectionHandler, DictionarySectionHandler, SingleTagSectionHandler.
Чтобы описать в конфигурационном файле собственную секцию, следует использовать тэг configSections. Вложенные элементы section данного тэга имеют атрибут name – имя секции, и атрибут type – полное имя класса-обработчика. Рассмотрим следующий пример конфигурационного файла:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<section name = "mySection"
type = "System.Configuration.NameValueSectionHandler" />
</configSections>
<mySection>
<add key="key1" value="Alex" />
<add key="key2" value="Volosevich" />
</mySection>
</configuration>
Этот файл задает пользовательскую секцию с именем mySection и указывает, что для ее обработки следует использовать NameValueSectionHandler, то есть, содержимое секции будет доступно как NameValueCollection.
Для чтения информации из пользовательской секции применяется метод ConfigurationSettings.GetConfig(). В качестве параметра методу передается имя секции. Метод возвращает значение типа object, которое следует привести к типу класса-обработчика секции. Следующее приложение читает информацию из своего (описанного выше) конфигурационного файла:
using System;
using System.Configuration;
using System.Collections.Specialized;
class CustomConfig {
static void Main() {
NameValueCollection nvc =
(NameValueCollection)ConfigurationSettings.GetConfig("mySection");
Console.WriteLine(nvc["key1"]);
Console.WriteLine(nvc["key2"]);
}
}
Следует иметь в виду, что файл конфигурации читается и разбирается исполняемой средой один раз, при загрузке приложения. Поэтому все изменения, которые внесены в этот файл, не буду иметь эффекта до перезагрузки приложения. Если такое поведение является неприемлемым, то можно воспользоваться классом System.IO.FileSystemWatcher. Как следует из его названия, класс позволяет отследить изменения, происходящие с файлом (или несколькими файлами). Подробности работы с классом FileSystemWatcher можно найти в .NET Framework SDK.