вторник, 10 апреля 2012 г.

Как работает архитектура в Composite C1 CMS (1)

Это очень близкий к тексту  (но не машинный :) ) перевод статьи на StackOverflow, посвященной архитектуре Composite C1: How does the architecture work?

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


При разночтениях и непонятностях, обращаться к оригиналу :)

***

От запроса до отображенной страницы

Конкретный путь, который проходит запрос, зависит от версии Composite C1, которую вы используете, так как вследствие изменения в версии 2.1.2 используется маршрутизация (Routing). Итак, давайте посмотрим:
  • < 2.1.2
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) в коллекцию маршрутов (Routes), которая "смотрит" на входящий путь и определяет, является ли он допустимой C1-страницей. Если это так, то возвращает экземпляр ~/Rendererings/Page.aspx, готовый к выполнению. 

Итак, теперь у нас имеется экземпляр IHttpHandler, готовый к созданию страницы, которая будет отправлена клиенту. Сам код IHttpHandler - не составит труда изучить, так как он находится в ~/Renderers/Page.aspx.cs.
  • OnPreInit
Здесь мы определяем, идентификатор (Id) какой страницы и на каком языке запрашивается, а также, находимся ли мы в режиме предварительного просмотра, какова область доступа к данным и т.п.
  • OnInit
А теперь мы извлекаем содержимое из каждого "заполнителя контента" (content placeholder) нашей страницы, и выполняем функции, которые могут там быть. Для этого вызывается  Composite.Core.WebClient.Renderings.Page.PageRenderer.Render, в который передается текущая страница и наши "заполнители". Внутренне, будет вызван метод  ExecuteFunctions, который пройдется по всему контенту и рекурсивно "разрешит" (resolve) элементы C1-функций (<f:function />), выполнит их и заменит элементы результатами выполнения функций. Выполнение будет продолжаться, пока больше не останется функций - это в том случае, если сами функции возвращают в качестве результатов другие функции.

И теперь весь контент "завернут" (wrapped) в элемент управления ASP.NET веб-форм, и вставлен в нашу веб-форм-страницу. А так как C1-функции могут возвращать элементы управления веб-форм как пользовательские элементы управления (UserControls) и т.п., им необходимо работать правильно и запускать жизненный цикл событий веб-форм.

И это практически все. Обработка/отображение запрашиваемой страницы - это очень просто, и очень "расширяемо". Например, существует расширение, которое делает возможным использование эталонных страниц (MasterPages), которые просто и очень элегантно подключаются к этому потоку обработки. А так как мы используем Routing для определения, какой обработчик использовать, то можно вообще забыть о ~/Rendering/Page.aspx и возвращать MvcHandler, если вы фанат MVC.

Программные интерфейсы (API)

Что касается более фундаментальных программных интерфейсов (API), их - немало. Все зависит от того, что вы хотите сделать. Но будьте уверены, что бы это ни было, всегда есть интерфейсы, необходимые для выполнения задачи.

На самом низком уровне находится "Уровень данных" (Data Layer), вокруг которого сосредоточено большинство программных интерфейсов и фасадов. То есть, большинство задач можно выполнить, работая с необработанными данными, а не обращаясь к фасадам каждый раз. Это возможно благодаря тому, что большая часть конфигурации C1 реализована с помощью своего собственного уровня данных для хранения конфигурации.

Разработчикам ядра системы Composite C1 еще предстоит проверить/выполнить рефакторинг и задокументировать все программные интерфейсы в системе и таким образом работать с понятием "публичного программного интерфейса" и того, что может стать с программным интерфейсом, когда на него есть спрос. Сам API весьма стабилен, но без гарантий.

Документация по публичному API есть в сети: http://api.composite.net/ (англ.)

Функции

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

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

О функциях можно почитать здесь: http://users.composite.net/Functions (англ.), а о том как использовать, например,  Razor для создания функций - здесь: http://docs.composite.net/Razor-Functions (англ.).

(продолжение следует...)

***

Ссылки по теме на некоторые материалы на русском:

Комментариев нет:

Отправить комментарий