Введення в. NET Framework

Один з ключових елементів архітектури Microsoft. NET – середа. NET Framework. Вона відповідає за реалізацію нового режиму виконання (а значить, і розробки) додатків на локальному комп'ютері. Мова йде про додаткової сполучною середовищі між додатками і ОС, з одного боку, і між програмними компонентами однієї програми – з іншого.


У цій статті мені хотілося б зробити загальний огляд архітектури. NET Framework, щоб показати основну логіку роботи на концептуальному рівні, не дуже вдаючись у деталі її реалізації. Більш детальне вивчення середовища ще попереду.


З точки зору розробника ОС Windows – це в першу чергу набір базових функцій Win API, реалізованих у вигляді DLL. До 1993 р. в Windows основною моделлю створення багатокомпонентних програм було саме використання допоміжних модулів підтримки у вигляді DLL (свого часу прийшли на зміну класичному варіанту, який передбачає створення єдиного виконуваного модуля шляхом включення до нього процедур з двійкових LIB-бібліотек). У 1993 р. Microsoft запропонувала нову модель багатокомпонентних додатків – COM (Common Object Model). За великим рахунком, головна ідея тут полягає в застосуванні на додаток до виконуваного коду метаданих, що забезпечують автоматичний контроль за передачею параметрів (а також уніфікація форматів параметрів).


Звичайно, можна говорити про достоїнства COM в порівнянні з традиційними DLL (хоча гідності завжди супроводжуються і недоліками, в даному випадку у вигляді зниження продуктивності), але я категорично не згоден з висловлюваннями деяких авторів, зміст яких зводиться до наступного: "Після виходу COM розробники зрозуміли, що їм більше не треба писати весь код додатків з нуля". Якщо вдуматися, використання готових компонентів – ключова технологія програмування протягом всієї історії цього виду діяльності.


Чесно кажучи, я ніколи не відчував особливого захоплення від конкретної реалізації ідей COM і ще кілька років тому висловлював думку, що вона несе в собі серйозну загрозу втрати керованості Windows-додатків (Див., наприклад "Проблеми компонентної моделі ПЗ", PC Week / RE № 32/97). Представляючи першу бета-версію. NET Framework, корпорація Microsoft відкрито заявила, що одна з цілей реалізації цього середовища – рішення проблеми DLL Hell ("пекло DLL"), пов'язаної з використанням загальних DLL і OCX, які неконтрольованим чином змінюють версії, видаляються і т. п. Інші ключові завдання. NET Framework – уніфікація бібліотек функцій для різних мов, а також підвищення контролю за додатками з точки зору безпеки та ефективного використання ресурсів.


Структура і логіка роботи


Структура. NET Framework представлена на рис. 1. Як видно, мова йде фактично про єдине середовище виконання програм та підтримки їх розробки. Саме тут зібрано базові класи для всіх мов програмування, реалізовані у вигляді бібліотеки ядра System, а також великої кількості (понад 20) спеціалізованих бібліотек з іменами System.Data, System.XML і т. д. Над ними розташовується набір засобів формування виконуваних модулів різного типу (знову ж єдиний для різних мов).

Рис. 1. Структурна схема. NET Framework.


Власне, з точки зору розробки додатків саме в цьому полягає новизна (але лише відносна, для Windows-програмування) даного рішення: допоміжні функції відокремлені від бізнес-логіки додатків, що реалізується за допомогою конкретних мов. Крім очевидної переваги такої уніфікації функцій (навіщо писати окремі функції, що обчислюють синус, для різних мов?), Це створює гарні передумови для поліпшення управління оперативною пам'яттю. Адже, як відомо, величезне число проблем надійності програм пов'язана з використанням різних механізмів динамічного розподілу простору у різних мовах.


Зверху розташовуються самі інструменти розробки, представлені в даному випадку системою Visual Studio. NET, в якій кожна з мов взаємодіє з. NET Framework через загальний мовний інтерфейс. Докладне вивчення VS.NET ще попереду, а зараз обмежимося кількома зауваженнями.


З одного боку, такий механізм дозволяє досить просто підключати до розглянутої середовищі різні мови. В даний час про створення таких коштів (COBOL, FORTRAN, Perl і т. п.) оголосили вже більше 20 незалежних розробників. У той же час майже у всіх цих інструментів є альтернативні варіанти середовища, які працюють поза VS.NET і безпосередньо взаємодіють з. NET Framework.


З іншого боку, така уніфікація автоматично нівелює функціональні можливості різних мов, в значній мірі зводячи проблеми вибору конкретного інструменту до прихильності конкретних людей того чи іншого синтаксису. Це сьогодні особливо добре видно на прикладі VB.NET і C #. Оскільки, говорячи про платформі. NET, нам ніяк не уникнути порівняння її з Java 2 Platform, то помітимо, що відмінність між ними в тому, що в першому випадку є різні синтаксичні форми для єдиного. NET-мови. До якої міри виправданий відмову від специфіки мов (яка виявлялася в різній їх ефективність для вирішення різних предметних завдань) – на цю тему можна подискутувати окремо.


Common Language Runtime


Вище ми говорили про компоненти. NET Framework, що відносяться до процесу розробки додатків. CLR (Common Language Runtime, загальна для мов середовище виконання) – це наріжний камінь у фундаменті організації обчислювальних процесів всієї концепції. NET. Саме тут повинні вирішуватися основні завдання підвищення надійності та безпеки програм, а також платформної незалежності. CLR – це окрема велика тема, тому ми розглянемо її лише тезисно.


Всі виконувані модулі. NET-додатків (будемо називати їх CLR-модулями) реалізуються не у вигляді машинного коду (native, "рідного" для даного комп'ютера), а з допомогою так званого байт-коду за специфікаціями проміжної мови Microsoft Intermediate Language (MSIL). Іншими словами, кожен сумісний с. NET-компілятор повинен перетворити вихідний код на мові високого рівня в двійковий MSIL-код, який вже потім буде виконуватися в середовищі CLR. Ідея та реалізація подібного підходу зовсім не нові, для Basic і Virtual Pascal це робилося ще в 1970-х, а про Java відомо і нинішньому поколінню розробників.


Однак, на відміну від Java, CLR буде виконувати код не в режимі класичного інтерпретатора, а шляхом попередньої компіляції в машинний код окремих фрагментів програми або цілого додатка (мал. 2). Перший варіант – основний, при цьому застосовується так званий Just-In-Time компілятор, який виконує перетворення MSIL в машинний код по мірі звернення до відповідних процедур (тобто невживані фрагменти програми зовсім не компілюються). Даний підхід також добре відомий; він, зокрема, вже більше шести років використовується в платформі "1С: Підприємство".

Рис. 2. Схема компіляції. NET-додатків.

Як відомо, режим інтерпретації має дві головні переваги в порівнянні з використанням машинного коду: підвищення безпеки програм (точніше, захищеності системи в цілому від дії конкретних програм) і спрощення адаптації програм до конкретної апаратної платформи. З урахуванням цього розглянемо структуру CLR-модулів.


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


Виконуваний код в основному представлений у вигляді "керованого коду" (можливі й фрагменти "некерованого коду", але вони будуть відтепер великою рідкістю). Це означає, що CLR не просто перетворює MSIL в машинні інструкції, а виконує ці дії з урахуванням певних зовнішніх установок. Наприклад, модуль1 може задати свій власний набір прав, що надається викликається їм Модулю2, заборонивши, зокрема, будь-які операції зміни файлів.


Ця можливість широко використовується в багатокористувацької Інтернет-грі для програмістів "Тераріум", анонсованої на форумі PDC 2001. У ній кожен може написати програмні модулі, що реалізують вибрані стратегії, які інші учасники завантажують на свої комп'ютери. Безпека тут забезпечується саме завдяки чіткому контролю за допустимими діями "чужорідних тіл". Загалом, в CLR ми бачимо реалізацію ідей Інтернет-браузерів, які представляють проміжне середовище виконання програм, але тільки зі значно більш високим рівнем керованості прав.


Що стосується платформної незалежності, то CLR, здавалося б, має для цього всі передумови, оскільки передбачає наявність JIT-компілятора (як і в Java). Але я не поділяю оптимізму деяких експертів, які говорять про можливість появи найближчим часом подібних засобів, наприклад, для Linux. По-перше, CLR спочатку досить істотно задіє базові служби Windows. По-друге, Microsoft зовсім інакше, ніж Java-спільнота, трактує поняття багатоплатформності: JIT-компілятори з'являться для різних типів апаратури (кишенькові ПК, мобільні телефони і т. п.), але працювати вони будуть тільки в середовищі Windows. NET.


Об'єкти COM і. NET


Чесно кажучи, я поки що не до кінця зрозумів, в чому якісну відмінність цих двох типів об'єктів, принаймні, в рамках локального комп'ютера. Можливо, є якісь радикальні зміни в протоколах взаємодії, але внешне.NET зараз являє собою лише модернізований варіант COM, мабуть, лише з двома видимими відзнаками.


По-перше, реалізована ієрархічна система імен об'єктів типу, що отримала назву "простір імен". Тепер замість плоского ідентифікатора "ІмяПріложенія.ІмяКласса" можна використовувати "ІмяПріложенія.Імя1.Імя2 …. ІмяКласса".


По-друге, змінено порядок реєстрації об'єктів, що безпосередньо пов'язано з появою ще одного нового терміна – збірка (Assembly).


Як відомо, COM-модулі можуть перебувати в будь-якому каталозі і стають доступними іншим програмам за допомогою реєстрації в Реєстрі (де виконується зв'язка ідентифікаторів ProgID, GUID і фізичного адреси файлу). У випадку. NET реєстрація об'єктів фактично виконується індивідуально для кожного додатку, що розробляється, при цьому файл компонента просто копіюється в локальну збірку (окремий каталог даного проекту). Аналогічним чином. NET-додаток завантажує до себе копію COM-об'єкта, зареєстрованого в Реєстрі, і, у свою чергу,. NET-об'єкт може бути зареєстрований в якості модуля COM. Загальні. NET-компоненти (Shared Assemblies) для різних додатків зберігаються в області Global Assembly Cache, яка представляє собою просто каталог з фіксованим ім'ям WINNTassembly.


Здавалося б, такий підхід повинен надійно вирішити згадану вище проблему DLL Hell, але я б не поспішав з висловленням захоплення. Мене насторожує можливість появи на одному комп'ютері величезного числа різних версій по суті одного й того ж компонента, що загалом суперечить класичним принципам програмування. Наприклад, ви виявили тривіальну помилку в компоненті і перекомпілювати його. А як тепер внести зміни в усі збірки, де він використовується? Не кажучи вже про те, що тепер одне і те ж розширення DLL використовується вже не для двох, а для трьох абсолютно різних типів бібліотек: звичайні бібліотеки, COM і. NET.


Приклад взаємодії компонентів


Тепер спробуємо подивитися на прикладі, як же працює модель взаємодії. NET-компонентів. У середовищі Visual Studio. NET відкриємо новий проект типу Class Library для мови Visual Basic і введемо наступний код для реалізації функції, яка повертає поточний час у відповідності із заданим форматом:








Public Class MyClass1
     Public Function NowTime _
                    ByVal ShowSeconds As Boolean) _
                    As String
"Отримуємо поточний час
            If ShowSeconds Then
"Повернення" довгого "формату часу
                    Return Now.ToLongTimeString
Else "" короткий "формат
                    Return Now.ToShortTimeString
             End If
     End Function
End Class


У цілому ця маніпуляція нічим не відрізняється від створення COM-об'єкта у VB 6.0, за винятком лише синтаксису операції повернення значення функції (раніше ми б просто написали NowTime = Now).


Подивимося тепер на структуру проекту у вікні Solution Explorer (рис. 3). Відзначимо, що фізично наш проект називається ClassLibrary3, а логічне ім'я бібліотеки – MyClassLibrary (сенс цих компонентів проясниться надалі). Крім модуля класу, тут в явному вигляді описані три посилання на базові класи, підключені до проекту за замовчуванням. Втім, насправді підключених класів набагато більше (Наприклад, в їх число входять всі класи бібліотеки Microsoft.Visual Basic). Тут же видно новий модуль з описом даної збірки AssemblyInfo.vb, вміст якого можна не тільки подивитися, але і відредагувати (Рис. 4). Крім того, видно, що до проекту були автоматично підключені ще два базових класу (див. ключове слово Imports) і що дану бібліотеку можна зареєструвати і в якості COM-об'єкта – тут прописаний її GUID.

Рис. 3. Структура проекту ClassLibrary.

Рис. 4. Опис збірки проекту.

Тепер створимо DLL і подивимося каталог ClassLibrary3, куди записані файли проекту (рис. 5). Результуючий файл ClassLibrary3.dll знаходиться в підкаталозі BIN, а в OBJ – ще кілька копій цієї ж DLL, отриманих в результаті налагодження.

Рис. 5. Склад файлів проекту.

Для налагодження сервера створимо клієнтську програму у вигляді Console Application, в якій за допомогою сформованого раніше компонента спробуємо отримати поточний час. Для цього відкриємо вікно Add Reference і за допомогою кнопки Browse підключимо до проекту бібліотеку ClassLibrary3.dll (рис. 6). Введемо такий код:








Module Module1
     Sub Main()
          Dim tc As New ClassLibrary3.MyClass1()
           tc = New ClassLibrary3.MyClass1()
          MsgBox(tc.NowTime(True))
     End Sub
End Module

Рис. 6. Підключення. NET-компонентів.

Запустимо його на виконання і переконаємося, що все працює, як задумано. Принаймні, зовні все не відрізняється від того, як ми раніше працювали з COM-об'єктами (тільки все тепер робиться помітно повільніше). Але відзначимо один цікавий момент. Знову відкриємо проект ClassLibrary3 і замінимо в ньому старий код на такий варіант:








Namespace MyTimeComponent
     Public Class MyClass2
          Public Function HelloAll() As String
Return "Привіт всім!"
          End Function
     End Class
End Namespace

Відкомпілюємо його, повністю замінивши стару DLL. Але якщо ми зараз зайдемо в каталог ConsoleApplication2Bin, де зберігається створений раніше виконуваний файл клієнтського проекту, і запустимо його на виконання, то він буде працювати без проблем в старому варіанті. Чому? Та тому, що в цьому ж каталозі ви виявите попередній варіант ClassLibrary3.dll, яка була автоматично переписана при підключенні відповідної посилання.


Тепер знову відкриємо проект ConsoleApplication2 в середовищі VB.NET – і тут ми відразу побачимо по виділенню помилок синтаксису, що він не може знайти об'єкт з ім'ям ClassLibrary3.MyClass1. Виправимо код для роботи з новим варіантом створеного компоненти:








Module Module1
     Sub Main()
          Dim tc As New _
                    ClassLibrary3.MyTimeComponent.MyClass2()
          tc = New _
                    ClassLibrary3.MyTimeComponent.MyClass2()
          MsgBox(tc.HelloAll)
     End Sub
End Module


Стає зрозумілим сенс операторних дужок Namespace, використаних в коді класу, – з їх допомогою описується ієрархічна система імен об'єктів. Підправимо цей код, щоб можна було застосовувати більш компактне звернення до імен об'єктів:








Imports ClassLibrary3.MyTimeComponent
Module Module1
     Sub Main()
          Dim tc As New MyClass2()
          tc = New MyClass2()
          MsgBox(tc.HelloAll)
     End Sub
End Module


Тепер "сухий залишок": що ж нового ми побачили на цьому простому прикладі в порівнянні з традиційним використанням COM-об'єктів?


По-перше, проблема узгодження версій застосовуваних компонентів вирішується тривіальним копіюванням потрібних файлів в каталог клієнтського додатку (у тому числі за допомогою створення спеціальної копії COM-бібліотек). По-друге, за допомогою операторних дужок Namespace ми можемо створювати ієрархічну систему імен об'єктів на відміну від двухзвенной DllName.ClassName, прийнятої в COM, яка тепер є окремим випадком.


Покажемо детальніше, як створити таку систему імен, на прикладі проекту типу Class Library та імені ClassLibraryN:








"Це об'єкти першого рівня
Public Class Class1
"Набір функцій і методів класу
End Class


Namespace MyTimeComponent
"Об'єкти другого рівня
      Public Class Class1
"Набір функцій і методів класу
      End Class
            Public Class Class2
"Набір функцій і методів класу
      End Class
      Namespace MyComp2
"Об'єкти третього рівня
            Public Class Class1
"Набір функцій і методів класу
      End Class
   End Namespace
End Namespace


Відповідно, у клієнтському додатку використовувані нами класи будуть описані в такий спосіб:








Dim t1 As ClassLibraryN.Class1
Dim t2 As ClassLibraryN.MyTimeComponent.Class1
Dim t3 As ClassLibraryN.MyTimeComponent.Class2
Dim t4 As ClassLibraryN.MyTimeComponent.MyComp2.Clas


Зверніть увагу, що тут ми спеціально використовували однакове ім'я Class1 для різних об'єктів (що знаходяться в зоні дії різних просторів імен).


Звичайно, ці нововведення корисні, але я б поки уникав використання епітетів "революційні". До того ж треба подивитися, як це все працює в реальних проектах.


Добре забуте старе


Отже, ідея. NET Framework зрозуміла: уніфікувати набір базових програмних функцій (бібліотеки класів) і підвищити керованість додатків, у тому числі з точки зору взаємодії їх компонентів (CLR). Все це дуже похвально, тому що дійсно може допомогти вирішити існуючі сьогодні проблеми створення складних програмних комплексів. Однак важко позбутися думки про те, що всю цю "новизну" ми десь вже бачили …


Дійсно, за розмовами про DLL, об'єктних бібліотеках і збірках та інше ми якось призабули, що проблема повторного використання програмних компонентів і їх уніфікація виникла не 10 років тому. Саме для вирішення цього завдання ще років 40 тому була реалізована ідея поділу процедур компіляції (трансляція вихідних модулів в об'єктні) і компонування (об'єднання об'єктних модулів в один завантажувальний), що мала на увазі, зокрема, що для створення однієї програми можна застосовувати різні мови програмування, в тому числі з використанням єдиних бібліотек підпрограм.


При цьому ще за часів MS-DOS широко застосовувалася технологія, яка дозволяла або виділити допоміжні функції програми у вигляді автономного модуля підтримки (повного аналога нинішніх DLL), або включити їх до складу єдиного виконуваного файлу. І ніякого DLL Hell!


Звичайно, такі паралелі досить умовні, але все ж залишається деякий почуття занепокоєння: чому реалізація загалом досить простих ідей тягне за собою таке ж швидке зростання вимог до апаратних ресурсів? Може бути, для того, щоб ефективніше завантажити додаткові обчислювальні потужності, які постійно з'являються в результаті дії закону Мура?


До речі, що ось що з цього приводу говориться у книзі Девіда Платта "Знайомство з Microsoft. NET": ". NET Framework змусить Intel випускати більш швидкі процесори і більше чіпів пам'яті. Дехто з відділу маркетингу Microsoft стверджує, що. NET-додатки по швидкості не поступаються іншим, але це не так і ніколи так не буде ".


Схожі статті:


Сподобалася стаття? Ви можете залишити відгук або підписатися на RSS , щоб автоматично отримувати інформацію про нові статтях.

Коментарів поки що немає.

Ваш отзыв

Поділ на параграфи відбувається автоматично, адреса електронної пошти ніколи не буде опублікований, допустимий HTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

*

*