Представляємо MEF.DEV preview

Хмарна платформа MEF.DEV надає можливості прискорення розробки, хостингу та управління використанням додатків для незалежних розробників і компаній-розробників на основі Managed Extensibility Framework за допомогою гнучкого процесу розробки на принципах безперервної інтеграції. Вона має зручний інтерфейс, який спрощує процес розробки інтеграційних програм з хорошим рівнем угоди про обслуговування і на основі затверджених на підприємстві стандартів авторизації, аутентифікації, керованого розгортання зі стандартизованими підходами до моніторингу та SOX-контролів

До базових функцій платформи відносяться процеси, що вимагають стандартизації в рамках процесу розробки програмного забезпечення конкретного підприємства - тим самим встановлюючи «з коробки» стандартні підходи щодо ряду важливих фаз SDLC процесу:

REST API в якості основного елемента платформи розширює функціональність доступних в ній плагінів, наприклад BSS системи, надаючи доступ до її ресурсів, таким як особові рахунки, абоненти або послуги, використовуючи унікальні значення URI для зовнішньої взаємодії (system-to-plugin) або назви сутностей в рамках одного домена - для внутрішньої взаємодії (plugin-to-plugin). Щоб використовувати REST API, досить відправити HTTP запит і проаналізувати відповідь. REST API використовує JSON або XML в якості формату обміну в поєднанні зі стандартними методами HTTP GET, PUT AND POST:

  • GET повертає дані. Цей метод не змінює дані, що зберігаються на сервері
  • PUT змінює існуючий запис даних по ID і повної моделі даних
  • POST створює новий запис даних
  • DELETE видаляє запис даних по ID

Сутності як унікальні шляхи

Сутності забезпечують доступ до бізнес-логіки та конкретної (нативного) взаємодії даних за допомогою Managed Extensibility Framework (MEF). MEF набагато більше, ніж впровадження залежності (Dependency Injection) або інверсія управління (Inversion of Control) - це дає Enterprise-розробникам більш просту настройку і послідовне управління в величезних проектах, не піклуючись про те, коли, де і як налаштований конкретний додаток/плагін/модуль, і незалежно від того, як вони використовують цей додаток/плагін/модуль - отримуючи саме ту реалізацію, яку вони хочуть. Іншими словами, після того, як один розробник публікує додаток на MEF.DEV платформу, інші розробники, що створюють інші плагіни, можуть використовувати даний плагін або його нову версію в реальному режимі часу без перезавантаження - тобто "на льоту"..

Візуалізація вмісту конкретного плагіна (фактично реалізації конкретного розробника) дає прозорість для всіх інших учасників платформи, наприклад візуалізація плагіна Natec.Entities для домену BSS виглядає наступним чином:

Формат OpenAPI

Ми хочемо поліпшити ваш робочий процес розробки інтеграції за допомогою нашого REST API - з цієї причини ми створили інструмент для гнучкого і безперервного процесу інтеграції для корпоративного SDLC процесу. На даний момент ми пропонуємо загальний плагін (це всього лише один файл), який можна використовувати в процесі самостійної розробки додатків - Ви можете отримати також «з коробки» автоматично згенерувала документацію для створених Вами сутностей на основі атрибутів-декораторів.

Ви можете переглянути приклади плагінів в нашому репозиторії GitHub. Відео-уроки для розробників доступні за посиланням

Призначення MEF

Які ж завдання покликаний вирішити MEF? в .NET-середовищі не існувало єдиного інструменту для вирішення завдань розширення додатків, тому, коли таке завдання виникало, кожен розробник вирішував його по-своєму, в міру своїх знань, умінь та вимог завдання. Цілком очевидно, що ця ситуація призводить до створення коду, який архітектурно (або принципово) несумісний один з одним

MEF націлений на подолання цієї проблеми і пропонує єдиний спосіб вирішення архітектурних завдань розширюваності додатки. Досягнення мети MEF - поширення однакового підходу - дозволить спростити нам розробникам життя і зробити супровід чужого коду або написання розширень до чужих додатків значно простіше і в знайомій (закономірної) манері

В ідеальній перспективі, розробник, який вивчив MEF, буде здатний (без особливих складнощів і тривалого вивчення архітектури) розробляти компоненти для всіляких проектів на платформі .NET, написаних будь-якими іншими компаніями або окремими людьми. І, таким чином, MEF здатний вирішити завдання взаєморозуміння між розробниками, пропонуючи спільну мову спілкування.

Основи

Застава фактичної успішності MEF як інструменту криється в його простоті. MEF побудований всього на трьох функціональних частинах: імпорт, експорт і композиція. Використовуючи імпорт ви характеризуєте частини вашого застосування як здатні до розширюваності. Сторонній розробник, використовуючи функції експорту, створює окремий компонент (частина, плагін), призначений для вашого застосування. І, в ході виконання, ви використовуєте функції композиції для того щоб з'єднати частини імпорту з частинами експорту. Розглянемо ці етапи докладніше.

Імпорт

На малюнку нижче дано визначення якогось класу, який реалізує експортовану частину розширення в MEF.

Тут визначається автоматична властивість, тип якої визначається таким собі інтерфейсом IPlugin. За допомогою атрибута Import, який є частиною інфраструктури MEF, властивість позначається як здатна до імпорту. Саме властивість таким чином стає частиною імпорту, а типом частини буде інтерфейс IPlugin.

Зверніть увагу на параметр атрибута Import: typeof (IPlugin) в даному випадку визначається так званий контракт MEF. Контрактом називається унікальний ідентифікатор, який однозначно визначає частини імпорту та частину експорту і таким чином дозволяє MEF з'єднати обидві частини в процесі композиції. Простіше кажучи, визначаючи контракт ви повідомляєте якийсь пароль, який має назвати частину розширення для того, щоб приєднатися до точки імпорту. Далі в цій главі контракти будуть розглянуті більш детально.

Експорт

Експортована частина

Тут визначається якийсь клас FirstPlugin, який реалізує інтерфейс IPlugin (частина імпорту вище визначена за допомогою нього ж). За допомогою атрибута Export з інфраструктури MEF клас позначається як частина, що експортується (можна сказати "плагін"). Зверніть увагу, параметром атрибута Export служить контракт оголошений як typeof (IPlugin).

Визначення однакового контракту при імпорті та експорті дозволяє MEF знаходити призначений друг-другу частини.

Композиція

Після визначення імпортованих і експортованих частин необхідно провести їх композицію

Композицією називає процес пошуку всіх визначених частин MEF, їх інстанцірованія і присвоєння примірників експортованих частин частинам імпорту. Іншими словами, в процесі композиції плагіни помічені атрибутом експорту підключаються до частин вашого коду, поміченими атрибутами імпорту.

Композиція

Тут створюється екземпляр контейнера композиції (контейнер - це частина інфраструктури MEF). Після чого, у контейнера викликається метод ComposeParts, серед параметрів якого є перелік елементів, в яких MEF повинен шукати частини для композиції. В даному випадку, this - це екземпляр поточного класу та new FirstPlugin () - це інстанціюваний плагін, позначений нами в попередній частині атрибутом Export.

Після виклику ComposeParts, в контейнері container будуть записані екземпляри this і FirstPlugin, а імпортована частина Plugin отримає значення примірника FirstPlugin.

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

Контракти

Контракти в інфраструктурі MEF грають важливу сполучну роль між частинами імпорту та експорту. Контракти обов'язково явно або неявно визначаються при імпорті або експорті частин. На малюнку вище в якості контракту використовується вираз typeof (IPlugin), яке унікально визначає тип інтерфейсу IPlugin.

Насправді інфраструктура MEF містить кілька можливостей визначення контракту при імпорті:

Варіанти визначення контрактів при імпорті

ImportAttribute(Type) за допомогою вказівки передачі типу (так як ми розглядали)
ImportAttribute(String) за допомогою передачі імені контракту у вигляді рядка - в цьому випадку, ви повинні обов'язково гарантувати унікальність такого рядка серед інших контрактів
ImportAttribute(String, Type) за допомогою передачі як імені контракту у вигляді рядка, так і його типу - це може виявитися корисним, коли з'являється потреба створити кілька різних контрактів для одного і того ж типу
ImportAttribute() в разі, якщо атрибутам імпорту (Import і інші) не був переданий тип контракту, то він буде визначений автоматично на підставі типу до якого цей атрибут застосовується. Таким чином, ви можете опустити параметр typeof (IPlugin).

У варіантах коли ім'я контракту не було передано воно формується автоматично за допомогою методу GetContractName, який повертає повне строкове визначення типу включаючи його простір імен. Як уже згадувалося, якщо не вказано тип контракту, то він так само виходить автоматично.

Для атрибутів експорту діють ті ж правила, що і при імпорті. Але при визначення експорту за допомогою атрибутів Export і інших важливо розуміти наступну поведінку: в разі, якщо не вказано тип і ім'я контракту вони будуть отримані автоматично на підставі типу елемента до якого застосовується атрибут. Іншими словами, якщо в прикладі на малюнку "Експортована частина" опустити параметр typeof (IPlugin), то інфраструктура MEF визначить контракт автоматично на підставі типу FirstPlugin, але не IPlugin, як нам того потрібно. Це означає, що якщо ви будуєте експортовану частину на основі базових інтерфейсів або класів, то вам необхідно явно вказувати для контракту його тип.

Підготовлено на основі матеріалів Книга MEF