субота, 1 вересня 2012 р.

C#. Концепція та синтаксис. Частина 7

Конфігурація в .NET

Конфігураційні файли дають змогу змінювати системні налаштування без повторної компіляції аплікації.
Конфігураційний файл - це текстовий файл, який містить XML-елементи (теги). Змістовна частина файла повинна бути розміщена всередині пари тегів <configuration> і </configuration>. Наступний код демонструє спрощений конфігураційний файл:
<?xml version="1.0" encoding="utf-8" ?> <configuration> <appsettings>
<add key="Application Name" value="MyApplication"/> </appsettings> <runtime>
<gcConcurrent enabled="enabled" /> </runtime> </configuration>
Приклад містить парні теги (<appsettings> і </appsettings>, <runtime> і </runtime>). Ці теги (а також довільні інші парні теги) можуть містити набори стрічок конфігурації. Якщо тег не містить інші теги, то закриваючий тег може бути відсутнім.
Регістр символів у конфігураційних файлах є істотним.
Простір імен System.Configuration містить декілька класів, призначених для роботи з конфігураційними файлами. Зокрема:

Клас___________________________ Опис___________________________________
AppSettingsReader                                              Читання значень секції appsettings
ConfigurationException                                     Обробка помилок конфігурування системи ConfigurationSettings                                        Доступ до конфігураційної секції у файлі
DictionarySectionHandler                                   Читання пар ключ-значення в заданій секції

Наприклад, для наведеного вище коду метод ConfigurationSettings.AppSettings["Application Name"] поверне значення "MyApplication".
У .NET Framework існує кілька типів конфігураційних файлів: комп'ютера, аплікації, системи безпеки.
У конфігураційному файлі комп'ютера machine.config зберігаються основні налаштування системи (вбудованих віддалених каналів зв'язку, ASP.NET, зв'язки складених модулів та інше). Конфігураційний файл комп'ютера, зазвичай, розташований у каталозі <install path>\CONFIG, де <install path> - папка інсталяції системи .NET Framework.
Конфігураційний файл аплікації містить налаштування конкретної прикладної програми. Для Windows-аплікації він має таку ж назву, як і exe-файл з доданим розширенням .config. Наприклад, WindowsApp.exe.config. Конфігураційний файл аплікації розташовують в каталозі аплікації.
Система конфігурації переглядає конфігураційні файли аплікацій після конфігураційного файла комп'ютера.
У конфігураційних файлах безпеки визначається набір правил, які виконує CLR для забезпечення захисту комп'ютера від несанкціонованого коду. Ці файли безпеки визначаються трьома рівнями політик системи безпеки:
          конфігурація політики підприємства
(<install path>\CONFIG\enterprise. config);
          конфігурація політики машини
(<install path>\CONFIG\security. config);
         конфігурація політики користувача (<USERPROFILE>\application data\Microsoft\ CLR security config\vxx.xx\security.config).
Конфігураційні файли безпеки захищені системою безпеки Windows.

Опишемо дві типові задачі керування аплікацією в .NET.
Перескеровування версій складених модулів. Припустимо, що деяка клієнтська програма Client.exe використовує загальнодоступний складений модуль SharedAssembly версії 1.0. З часом розробник програмного забезпечення випускає нову версію 1.1, в якій виправлено деякі помилки попередньої версії. Необхідно існуючій клієнтській програмі дати вказівку на використання нової версії модуля SharedAssembly.
Конфігурування каталогів. Інколи потрібно зробити доступними розподілені і складені модулі, проте не розміщувати їх у глобальний кеш. Існує два способи означення каталогу для складеного модуля: з допомогою елемента codeBase в конфігураційному файлі та з допомогою зондування. Перший спосіб доступний лише для розподілених складених модулів, а другий - і для приватних, і для розподілених.
Для розв' язування цих задач можна використати такий конфігураційний файл аплікації Client. exe . config:
<configuration> <runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.vl" <dependendAssembly xmlns=""> <assemblyIdentity name="SharedAssembly" publicKeyToken="7bc6357 2 63f5e6b7" /> <bindingRedirect oldVersion="1.0" newVersion="1.1" /> <codeBase version="1.1" href="file:C:\MyAsm" /> </dependendAssembly>
</assemblyBinding> </runtime> </configuration>
З допомогою тега <runtime> конфігурують налаштування середовища виконання. Умови генерування модуля розміщують всередині тега <assemblyBinding>, який, у свою чергу, містить тег опису залежностей <dependendAssembly>. Таких тегів опису залежностей може бути кілька, і кожен з них повинен містити тег <assemblyIdentity> ідентифікації модуля.
Задачу перескеровування версії складеного модуля вирішує тег <bindingRedirect>, який дає вказівку замість версії l.0 використовувати версію l.l. Значення oldVersion може бути також діапазоном версій, наприклад, l.0.ll.4-l.0.l7.56.
Тег <codeBase> вирішує задачу конфігурування каталогу. Атрибут version визначає, яка версія складеного модуля має завантажуватися з каталогу, заданого атрибутом href.
Конфігураційні файли можна редагувати як звичайні текстові файли. Однак ця процедура передбачає наявність специфічних знань і досвіду.
.NET Framework має декілька спеціалізованих інструментальних засобів конфігурування.
Інструментальний засіб mscorcfg.msc вбудований у консоль Microsoft Management Console (MMC) і може бути запущений командою mmc mscorcfg.msc.
З допомогою mscorcfg.msc можна виконувати такі задачі:
         конфігурація та управління складеними модулями (Assembly Cash, Configured Assemblies);
         установка віддалених налаштувань (Remoting Services Properties);
         конфігурація та управління безпекою (Runtime Security Policy);
         управління аплікацією (Applications).
Утиліта політики захисту доступу до коду Caspol.exe призначена для:
         адміністрування комп'ютера та рівнів політики;
         читання та зміна політики;
         перевірки повноважень, наданих складеному модулю.


Утиліта Caspol.exe може запускатися з такими
атрибутами:
Атрибут
Дія
-addfulltrust
Додає складений модуль, який реалізує клієнтський
assembly.dll
об'єкт безпеки, до списку повністю довірених

складених модулів для конкретного рівня політики
-addgroup
Додає нову групу коду до ієрархії груп коду
-listgroups
Надає інформацію про доступ до груп коду
-chggroup
Вносить зміни в умови членства у групі коду
-addpset
Додає новий набір повноважень до політики
-listdescription
Виводить ієрархічний список груп коду
-resolvegroup
Виводить список груп коду, членом яких є
assembly.dll
складений модуль
-resolveperm
Надає повноваження групі коду складеного модуля
assembly.dll

-user -listgroups
Виводить список груп коду на рівні користувача
-Enterprise
Виводить список груп коду на рівні підприємства
-listgroups

-security off
Забороняє .NET-безпеку
-security on
Дозволяє .NET-безпеку

Взаємодія з COM

COM-компоненти та .NET-компоненти орієнтовані на різні стандарти компіляції: двійковий стандарт COM та CLS-стандарт. Для взаємодії з моделлю COM бібліотека .NET містить низку програмних технологій та утиліт. Ці програми можна використовувати для генерування компонент проксі (proxi, проміжні програми), які розпізнаються як стандартами компіляції COM, так і .NET.
Щоб додати посилання на DLL COM, можна скористатися діалоговим вікном References інструментального середовища VS. У цьому випадку VS утворює компонент проксі .NET для DLL COM і копію DLL COM розташовує в каталог проекту .NET. Якщо імпортована DLL у своєму відкритому інтерфейсі посилається на інші DLL COM, то для кожної з них утворюється свій проксі та своя копія DLL.
Проксі описує DLL COM і є для неї делегатом, який пересилає виклики від клієнта .NET через служби COM до DLL COM. У термінології .NET такий проксі називають RCW (Runtime Callable Wrapper - оболонка часу виконання).
Значно більші можливості від діалогового вікна References для утворення проксі надає утиліта TblImp.exe (Type Library Importer), яка є частиною технології COM Interop - складової .NET Framework. Утиліта активізується командною стрічкою і повинна містити аргумент tlbFile - назву файла, який містить бібліотеку типів COM. Утиліта використовує низку опцій, опис яких можна отримати з командної стрічки такими командами: tblimp.exe /help tblimp.exe /?
Зокрема, опція /out filename дає змогу задати ім'я файла проксі:
TblImp.exe comlib.dll /out: comlibRCW.dll
Утворений файл виводу (RCW) потрібно розмістити в каталог проекту. За замовчуванням класи бібліотеки будуть розміщені у просторі імен з назвою файла RCW. Для перегляду вмістимого RCW можна використати утиліту дизасемблювання ILDasm. exe (IL Disassembler).
Припустимо, що імпортована бібліотека має клас classCom з методом Add (), який приймає два параметри та повертає їхню суму:
// comlib.dll (classCom)
public int Add(int X, int Y) { return X+Y;
}
Наведемо схематичний приклад виклику методу:
using comlibRCW;
comlibRCW.classCom objcom = new
comlibRCW.classCom();
int k; int x = 2;
int y = 3;
k = objcom.Add(ref x, ref y);
Зауважимо, що наявність RCW не замінює наявність COM- компонента. Тобто COM-компонент повинен бути зареєстрований у службах COM та відповідно налаштований утилітами Windows
(regsrv32 . exe, dcomcnfg. exe).
Пізнє зв 'язування з компонентами COM
Технологія взаємодії з COM, яка передбачає утворення RCW, використовує раннє зв'язування (early binding). У цьому випадку компілятор використовує бібліотеку типів компонента, щоб вбудувати адреси методів і властивостей компонента в виконувану клієнтську програму.
Пізнє зв'язування (late binding) передбачає, що програма отримає адреси властивостей або методів компонента у момент їхнього виклику. Механізм визначення цих адрес не є особливо швидким, отож використання пізнього зв' язування знижує продуктивність програми. Проте пізнє зв'язування дає змогу будувати значно гнучкіші програмні комплекси. Зокрема, можна використати поліморфізм COM компонент.
Для виклику методів об'єктів COM необхідно виконати такі
дії:
          з допомогою статичного метода GetTypeFromProgID класу Type (простір імен System.RunTime. InteropServices) утворити об'єкт Type (отримати інтерфейс IDispatch);
          використати цей об'єкт Type для утворення об'єкта COM з допомогою статичного методу CreateInstance класу Activator;
         утворити масив аргументів;
          використати метод InvokeMember об'єкта Type для виклику методів об'єкта COM.
Код реалізації набуде приблизно такого вигляду:
using System;
using System.Reflection;
Type objcomtype =
Type.GetTypeFromProgID("ComObjectName"); object objcom =
Activator.CreateInstance(objcomtype); object[] args = {2,3}; object obj;
obj = objcomtype.InvokeMember("Add", bindingFlags.InvokeMethod, null, objcom, args);
Для імпорту елементів керування ActiveX в .NET можна використати утиліту AxImp.exe (ActiveX Importer). Загальна схема активізації утиліти така:
aximp.exe [options]{file.dll | file.ocx}
Обов'язковий аргумент file.dll (або file.ocx) задає абсолютний або відносний шлях до файла ActiveX, який необхідно імпортувати.
Результатом роботи утиліти будуть два файли: проксі для модуля та елемент керування Windows (в термінах .NET). Наприклад, наступна команда генерує файли MediaPlayer.dll та AxMediaPlayer. dll для елемента керування Media Player:
aximp c:\winnt\system32\msdxm.ocx
З допомогою опцій утиліти AxImp назви файлів можна задавати.
Проксі MediaPlayer.dll дає змогу робити посилання на елемент ActiveX так, ніби він є звичайним неграфічним компонентом COM.
Елемент керування Windows AxMediaPlayer.dll дає змогу використовувати графічний аспект імпортованого елемента ActiveX у проектах Forms Windows .NET.
Для розташування зображення імпортованого елемента ActiveX на панелі керування IDE VS.NET необхідно вибрати його на сторінці .NET Framework Components діалогового вікна Customize ToolBox.
Для підготовки компонента .NET до використання службами COM застосовують утиліту RegAsm.exe (Register Assembly). Ця утиліта вводить інформацію про тип компонента .NET у системний реєстр.
Загальна схема виклику утиліти:
regasm.exe assemblyFile [options]
Аргумент утиліти assemblyFile задає складений модуль, який реєструють служби COM.
Наведемо можливий сценарій підготовки компонента .NET до використання службами COM на прикладі класу Points:
namespace Points { using System; public class Points {
// оголошення та реалізація класу
}
}
Цей сценарій налічує такі кроки:
         утворення стійкого імені складеного модуля з допомогою утиліти sn: sn.exe -k points.snk
         утворення файла AssemblyInfo.cs, який містить код
using System.Reflection;
[assembly: AssemblyKeyFile("points.snk")]
          компіляція файла AssemblyInfo.cs:
csc.exe /t:module /out:AssemblyInfo.dll AssemblyInfo.sc
         компіляція файла Points.cs: csc.exe /t:library
/addmodule:AssemblyInfo.dll Points.sc
         розташування результуючої dll у глобальний кеш gacutil.exe /i Points.dll
         реєстрація Points.dll у службах COM: regasm.exe Points.dll
Тепер можна виконати пізнє зв'язування зі складеним модулем .NET через служби COM. Наприклад, на Visual Basic це можна зробити так:
Option Explicit
Dim objPoints
Set objPoints = CreateObject("Points.Points")
Call MsgBox(objPoints.ToString())
Описаний механізм дає змогу утворити з пізнім зв'язуванням об'єкт .NET службами COM.
Можливо отримати значно ефективніше раннє зв'язування з компонентами .NET, якщо використовувати бібліотеку типів COM (файл * . t lb). Таку бібліотеку типів утворює утиліта експорту TlbExp. exe (Type Library Exporter).
Загальна схема виклику утиліти:
tlbexp.exe assemblyName [options]
Аргумент утиліти assemblyName задає складений модуль, бібліотека типів якого має експортуватися. Якщо опції утиліти відсутні, то утвориться файл із назвою складеного модуля та розширенням .tlb.
Зауважимо, що не можна експортувати бібліотеку типів складеного модуля, імпортованого утилітою TlbImp. Це обмеження не стосується складених модулів, які мають посилання на імпортовані утилітою TlbImp модулі.
На відміну від RegAsm, утиліта TlbImp лише утворює бібліотеку типів, однак не реєструє її.

1 коментар: