Как работает архитектура Composite C1? - PullRequest
20 голосов
/ 29 октября 2011

Может ли кто-нибудь дать высокоуровневое описание того, что происходит в ядре Composite C1? В частности, мне интересно знать, как работает архитектура подключаемых модулей и каковы основные компоненты системы, то есть когда поступает запрос о том, что происходит в архитектуре. Описание не должно быть слишком подробным, просто список шагов и участвующих классов.

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

1 Ответ

40 голосов
/ 30 октября 2011

От запроса к отображаемой странице

Конкретный путь, по которому идет запрос, зависит от версии C1, которую вы используете, поскольку она была изменена для использования Routing в версии 2.1.2. Итак, давайте посмотрим

  • <2.1.2 </li>

Composite.Core.WebClient.Renderings.RequestInterceptorHttpModule будет перехватывать все входящие запросы и выяснять, соответствует ли запрошенный путь действительной странице C1. Если это произойдет, URL будет переписан обработчику страницы C1 ~/Rendererings/Page.aspx

  • 2.1.1

Composite.Core.Routing.Routes.Register() добавляет маршрут страницы C1 (Composite.Core.Routing.Pages.C1PageRoute) в коллекцию маршрутов, которая просматривает входящий путь, выясняет, является ли она допустимой страницей C1. Если это так, он возвращает экземпляр ~/Rendererings/Page.aspx, готовый к выполнению.

Хорошо, теперь у нас есть экземпляр IHttpHandler, готовый заполнить страницу, которая будет возвращена клиенту. Фактический код для IHttpHandler легко увидеть, так как он расположен в ~/Renderers/Page.aspx.cs.

  • OnPreInit

Здесь мы выясняем, какой идентификатор страницы и какой язык был запрошен, и смотрим, находимся ли мы в режиме предварительного просмотра или нет, какой объем данных и т. Д.

  • OnInit

Теперь мы извлекаем контент из каждого заполнителя контента нашей страницы и исключаем его функции, которые он может содержать. Это делается путем вызова Composite.Core.WebClient.Renderings.Page.PageRenderer.Render, передавая текущую страницу и наши заполнители. Внутренне он вызовет метод ExecuteFunctions, который будет проходить по содержимому и рекурсивно разрешать элементы функции C1 (<f:function />), выполнять их и заменять элемент выходными данными функций. Это будет выполняться до тех пор, пока в содержимом не останется больше элементов функции, если функции сами выдают другие функции.

Теперь весь контент упакован в элемент управления Asp.Net WebForms и вставлен на нашу страницу WebForms. Поскольку функции C1 могут возвращать элементы управления WebForms, такие как UserControl и т. Д., Это необходимо для их правильной работы и запуска жизненного цикла событий WebForms.

И это в основном все. Рендеринг запрашиваемой страницы очень прост и очень расширяем. Например, есть расширение, которое позволяет использовать MasterPages, которое просто элегантно подключается к этому потоку рендеринга. И поскольку мы используем Routing для сопоставления используемого обработчика, также можно забыть о ~/Rendering/Page.aspx и просто вернуть MvcHandler, если вы фанат Mvc.

API

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

В глубине у нас есть Уровень данных, вокруг которого сосредоточено большинство других API и фасадов. Это означает, что вы можете делать большинство вещей, работая с необработанными данными, вместо того, чтобы постоянно проходить через фасады. Это возможно, поскольку большая часть конфигурации C1 выполняется с использованием собственного уровня данных для хранения конфигурации.

Базовая группа Composite C1 еще не провела валидацию / рефакторинг и не документировала все API в системе и, следовательно, работает с концепцией «публичного API» и того, что может стать API, когда есть потребность. Последний - чертовски стабильный API, но без гарантий.

Публичная документация по API находится в сети по адресу http://api.composite.net/

Функция

Функции являются фундаментальной частью C1 и представляют собой метод отвлечения логики от исполнения. В основном все, что либо выполняет действие, либо возвращает некоторые данные / строку / значения, может быть кандидатом на функции. На самом низком уровне функция - это класс .Net, реализующий интерфейс IFunction, но, к счастью, есть много более простых способов работы с ним. Из коробки C1 поддерживает функции, определенные как шаблоны XSLT, методы C # или Sql. Также существует поддержка сообщества для написания функций с использованием Razor или наличия функций ASP.Net UserControls (файлы .ascx).

Поскольку все функции регистрируются в C1 во время запуска системы, мы используем Composite.Functions.FunctionFacade для выполнения любой функции, имя которой мы знаем.Используйте GetFunction, чтобы получить ссылку на функцию, а затем Execute, чтобы выполнить ее и получить возвращаемое значение.Функции могут принимать параметры, которые передаются как реальные объекты .Net при выполнении функции.Также имеется полная поддержка вызова функций с разметкой Xml с использованием элемента <f:function />, что означает, что редакторы, дизайнеры, создатели шаблонов и т. Д. Могут легко получить доступ к множеству функциональных возможностей без необходимости знать, как писать код .Net.

Подробнее о функциях здесь http://users.composite.net/C1/Functions.aspx и о том, как использовать, например, Razor, для создания функций здесь http://docs.composite.net/C1/ASP-NET/Razor-Functions.aspx

Глобализация и локализация

C1 заполненамногоязычная поддержка в основном.Composite.Core.Localization.LocalizationFacade используется для управления установленными локалями в системе;Запросы, добавление и удаление.Локалями могут быть любые объекты CultureInfo, известные вашей системе.

Composite.Core.ResourceSystem.StringResourceSystemFacade используется для получения строк во время выполнения, которые соответствуют CultureInfo, в котором выполняется ваш запрос. Используйте это вместо жестких кодировок строк на своих страницах.или в ваших шаблонах.

Подробнее о локализации читайте здесь http://docs.composite.net/C1/HTML/C1-Localization.aspx

Глобальные события

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

События запуска Если вы пишете плагины, они могут иметь собственную фабрику.Другой код может использовать атрибут ApplicationStartupAttribute для вызова ядром Composite C1 при запуске веб-приложения.

События данных Вы можете подписаться на события добавления, редактирования и удаления данных (до и после), используя статические методы для Composite.Data.DataEvents<T>.Чтобы присоединиться к этим событиям при запуске системы, используйте атрибут ApplicationStartupAttribute.

Данные

Composite.Core.Threading.ThreadDataManager важны, если вашдоступ к уровню данных за пределами соответствующего запроса страницы C1.Это может быть пользовательский обработчик, который просто должен подавать все последние новости в виде RSS-канала, или вы, возможно, пишете консольное приложение.В этих случаях всегда не забывайте оборачивать код, который обращается к данным, следующим образом:

using(Composite.Core.Threading.ThreadDataManager.EnsureInitialize())
{
  // Code that works with C1 data layer goes here
}

Для доступа к данным и манипулирования ими рекомендуется НЕ использовать класс DataFacade, но обернуть весь код, который получает, обновляет или удаляет, илидобавляет такие данные

using(var data = new DataConnection())
{
   // Do things with data
}

IO

При работе с файлами и каталогами важно использовать эквивалентные классы C1 Composite.Core.IO.C1File и Composite.Core.IO.C1Directory для .NetФайл и каталог.Это связано с тем, что C1 можно разместить на Azure , где вы можете не иметь доступа к файловой системе так же, как на обычном Windows Server.Используя оболочки файлов и каталогов C1, вы можете быть уверены, что написанный код сможет работать и в Azure.

Консоль C1

Консольвся тема сама по себе и имеет много-много API.

Вы можете создавать свои собственные деревья, используя Composite.C1Console.Trees.TreeFacade или Composite.C1Console.Elements.ElementFacade и реализуя Composite.C1Console.Elements.Plugins.ElementProvider.IElementProvider.

Вы можете использовать Composite.C1Console.Events.ConsoleMessageQueueFacade для отправки сообщений с сервера клиенту, чтобы он делал такие вещи, как открытие окна сообщений, обновление дерева, фокусировка на конкретном элементе, открытие новой вкладки и т. Д.и т.д.

Composite.C1Console.Workflow.WorkflowFacade используется для получения экземпляров определенных рабочих процессов и взаимодействия с ними. Workflows - очень фундаментальная часть C1 и способ определения и выполнения многошаговых операций. Это позволяет сохранить рабочее состояние, т. Е. мастер 10 шагов сохраняется, даже если сервер перезагружается или происходит что-то еще непредвиденное. Workflows строятся с использованием Windows Workflow Foundation , так что вы знакомы с этим, вы должны чувствовать себя как дома

Существует также множество javascript-фасадов и методов, которые вы можете использовать при написании расширений для консоли. Гораздо больше, чем я мог бы осветить здесь, поэтому я воздержусь от того, чтобы даже начать здесь эту тему.

composite.config

Фундаментальная часть C1 - провайдеры, почти все состоит из провайдеров, даже большая часть их основных функций. Все в консоли от перспектив до деревьев и элементов и действий подается в С1 с поставщиками. Все стандартные функции, слой данных и все виджеты для использования с редактором Call Function передаются в C1 с поставщиками. Все строки локализации для использования с Ресурсами, пользователями и разрешениями, средствами форматирования URL и т. Д. - все поставщики.

  • Composite.Data.Plugins.DataProviderConfiguration

Здесь зарегистрированы все провайдеры, которые могут отвечать на методы DataFacade, Get, Update, Delete, Add и т. Д. Каждый провайдер сообщает системе, с какими интерфейсами он может взаимодействовать, и C1 гарантирует, что все запросы на определенные интерфейсы направляются соответствующим поставщикам данных.

  • Composite.C1Console.Elements.Plugins.ElementProviderConfiguration

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

  • Composite.C1Console.Elements.Plugins.ElementActionProviderConfiguration

Провайдеры действий могут добавлять новые элементы меню ко всем элементам в системе, основываясь на их EntityToken. Это очень полезно, если вы хотите добавить новые функции к существующему контенту, такие как управление версиями, безопасность экстрасети, пользовательские вырезки и вставки, и список можно продолжить.

  • Composite.C1Console.Security.Plugins.LoginProviderConfiguration

LoginProvider - это то, что консоль C1 будет использовать для аутентификации пользователя и позволит вам войти в систему или нет. К сожалению, это не очень открыто, но с некоторым размышлением вы должны быть готовы.

  • Composite.Functions.Plugins.FunctionProviderConfiguration

Composite C1 будет использовать все зарегистрированные FunctionProviders для заполнения своего внутреннего списка функций при запуске системы.

  • Composite.Functions.Plugins.WidgetFunctionProviderConfiguration

WidgetProviders используются в таких вещах, как редактор вызовов функций или в разметке форм, для визуализации пользовательского интерфейса для выбора данных.

  • Composite.Functions.Plugins.XslExtensionsProviderConfiguration

Пользовательские расширения для использования в шаблонах XSLT зарегистрированы здесь

И затем у нас есть несколько разделов для чистой конфигурации, таких как кэширование или что распараллеливать, но это не так интересно, как провайдеры.

Определение и использование разделов

Разделы в Composite.config и других связанных файлах .config являются полностью стандартной конфигурацией .Net и подчиняются ее правилам.Это означает, что для возможности использовать пользовательский элемент, например, т.е.Composite.Functions.Plugins.WidgetFunctionProviderConfiguration это должно быть определено как раздел.Раздел имеет имя и ссылается на тип, который наследуется от System.Configuration.ConfigurationSection.Composite использует Microsoft Enterprise Libraries для обработки большинства таких общих вещей, как конфигурация, ведение журналов и проверка, и поэтому все разделы Composites наследуются от Microsoft.Practices.EnterpriseLibrary.Common.Configuration.SerializableConfigurationSection.Теперь этот тип просто должен иметь свойства для всех элементов, которые мы хотим определить в .config-файле, и .Net автоматически обеспечит связь для нас.

Если вы хотитечтобы получить доступ к конфигурации для определенного раздела, вы должны позвонить Composite.Core.Configuration.ConfigurationServices.ConfigurationSource.GetSection(".. section name") и привести его к вашему конкретному типу и вашему желанию.

Добавление дополнительных свойств к уже определенным разделам

Обычно .Net будет жаловаться, если вы пишете элементы или атрибуты в файлах .config, которые не распознаются типом, отвечающим за раздел или за элемент.Это затрудняет написание действительно гибкой модульной системы, в которой внешние авторы могут добавлять конкретные параметры конфигурации своим поставщикам, и поэтому у нас есть понятие Ассемблер.Это класс ConfigurationElement с присвоенным ему атрибутом Microsoft.Practices.EnterpriseLibrary.Common.Configuration.ObjectBuilder.AssemblerAttribute, который в свою очередь принимает интерфейс Microsoft.Practices.EnterpriseLibrary.Common.Configuration.ObjectBuilder.IAssembler в качестве аргумента, который отвечает за получение этих пользовательских атрибутов и значений из элемента в файле .config и создание из него пригодного для использования объекта.Таким образом .Net не будет жаловаться на недопустимый файл .config, поскольку мы внедряем объект ConfigurationElement, который имеет свойства для всех наших пользовательских атрибутов, и мы можем получить их при чтении конфигурации через IAssembler

Слайды

На этих линиях можно найти несколько обзорных слайдов

Вдохновение и примеры

Проект C1Contrib на GitHub - очень хорошее введениекак взаимодействовать с различными частями С1.Это коллекция небольших пакетов, которые можно использовать как есть, или для вдохновения.Есть пакеты, которые манипулируют с динамическими типами, чтобы включить наследование интерфейса.Другие пакеты используют javascript api в консоли, в то время как другие показывают, как создавать провайдеров функций, деревья и команды подключения к существующим элементам.Существуют даже примеры того, как манипулировать с веб-сервисом Soap, который происходит между клиентом и сервером, чтобы вы могли заставить его работать так, как вы этого хотите.И этот список можно продолжить.

...