среда, 20 июля 2011 г.

Консольные приложения (15): Использование рабочих потоков (workflows)

Мы уже познакомились с тем, как к элементам дерева консольного приложения в C1 привязать стандартные действия (создать, изменить, удалить).

Теперь поговорим о пользовательских действиях, которые можно также привязать к элементам.

Их - три типа:
  • Запуск рабочего потока (workflow)
  • Открытие ASPX страницы в админке
  • Выполнение С1-функции, которая возвращает XHTML
В данном сообщении, рассмотрим запуск рабочего потока. В качестве примера я возьму уже готовое решение-образец, доступное на официальном сайте C1.

Рабочий поток
  1. Загрузите проект C1WorkflowDemo2.x.zip с сайта C1.
  2. Распакуйте архив (и запомните путь к нему).
  3. Откройте ваш веб-сайт в Visual Studio 2010. 
(Если вы запустили ваш веб-сайт в WebMatrix, то в окне WebMatrix с вашим сайтом  переключитесь на вкладку Files (слева внизу), и нажмите кнопку Visual Studio на панели (справа вверху).)

Теперь в Solution Explorer:
  1. Выберите решение вашего сайта (корневой элемент в дереве), и добавьте C1WorkflowDemo.csproj (путь вы помните) как существующий проект (File > Add > Existing Project...). Таким образом проект вашего сайта и проект C1WorkflowDemo будут в одном решении.
  2. Выберите проект C1WorkflowDemo и удалите существующие ссылки на указанные ниже файлы, а затем добавьте ссылки на те же файлы из папки /Bin проекта вашего сайта:
    1. Composite.dll
    2. Microsoft.Practices.EnterpriseLibrary.Common.dll
    3. Microsoft.Practices.EnterpriseLibrary.Validation.dll
  3. Выберите проект вашего сайта и добавьте ссылку на проект C1WorkflowDemo.
  4. Соберите (Build) проект C1WorkflowDemo.
C1WorkflowDemo.dll должна появиться в папке /Bin вашего сайта. Если нужно, обновите (Refresh) папку.

Я не буду подробно разбирать код проекта C1WorkflowDemo. (Вы можете прочитать о нем в статье "Forms Workflow" (на англ.)).

Укажу только некоторые моменты:
  • В папке /DataTypes находятся статические типы данных IProduct и IProductCategory. (О статических типах данных я уже писал.) Элементы этого типа будут использоваться далее для построения дерева.
  • Класс Initializer, который вызывается при старте C1, проверяет, созданы ли хранилища данных для типов IProduct и IProductCategory.
  • В папке /Workflows находятся "рабочие потоки конечных автоматов" (State Machine Workflows) для управления действий над элементами в интерфейсе пользователя: добавить (AddProductWorkflow), изменить (EditProductWorkflow), удалить (DeleteProductWorkflow) - в интерфейсе используются мастера.
Определения дерева и форм

В данном случае мы не будем сами создавать файл определения дерева и многочисленные определения форм. Я вам предлагаю загрузить и установить пакет, который создаст их для вас (а также добавит немного демо-данных). И мы их просто немного изучим.
  1. Загрузите пакет C1WorkflowDemoSetupPackage2.x.zip с официального сайта С1. (Распаковывать не нужно!)
  2. В разделе "Система" в админке С1, раскройте "Пакеты", "Установленные пакеты" и выберите "Локальные пакеты".
  3. Нажмите "Установить локальный пакет".
  4. В появившемся окне выберите загруженный ZIP-файл пакета и нажмите "Далее".
  5. И следуйте указаниям мастера как при установке пакета с сервера.
Когда пакет будет установлен, админка перезагрузится и в разделе "Контент" появится новый узел "C1 Workflow Demo - Products".


В нем уже будут некоторые демо-данные и вы сможете добавлять новые...


... а также изменять и удалять существующие. Особенностью этого является то, что будут использоваться не стандартные действия С1, а рабочие потоки (workflows), которые вы сами создали.

Сам пакет при установке делает следующее:
  • Вносит изменения в Composite.config, чтобы определения форм могли также хранится в папке /App_Data/Composite/Forms и копирует определения форм в эту папку. Их пять: три для добавления (там три шага в мастере) и по одному для изменения и удаления. На них же ссылаются рабочие потоки.
  • Копирует в папку /App_Data/Composite/TreeDefinitions определение дерева C1WorkflowDemoTree.xml.
Рассмотрим C1WorkflowDemoTree.xml поближе.

C1WorkflowDemoTree.xml

Практически все элементы и их атрибуты в этом файле должны быть для вас знакомы (если вы прочитали предыдущие 14 сообщений на тему "Консольные приложения")...

<?xml version="1.0" encoding="utf-8"?>
<ElementStructure xmlns="http://www.composite.net/ns/management/trees/treemarkup/1.0" xmlns:f="http://www.composite.net/ns/function/1.0">
  <ElementStructure.AutoAttachments>
    <NamedParent Name="Content" Position="Bottom" />
  </ElementStructure.AutoAttachments>
  <ElementRoot>
    <Children>
      <Element Label="C1 Workflow Demo - Products" Id="C1WorkflowDemo" Icon="pagetype-pagetype-rootfolder" OpenedIcon="pagetype-pagetype-rootfolder-open">
        <Actions>
          <WorkflowAction Label="Add product..."
                          ToolTip="Add a new product to this category"
                          Icon="page-add-page" PermissionTypes="add" Location="Add"
                          WorkflowType="C1WorkflowDemo.Workflows.AddNewProductWorkflow, C1WorkflowDemo" />
        </Actions>
        <Children>
          <DataElements Type="C1WorkflowDemo.DataTypes.IProductCategory" Icon="pagetype-pagetype-rootfolder" OpenedIcon="pagetype-pagetype-rootfolder-open">
            <Actions>
              <WorkflowAction Label="Add product..."
                              ToolTip="Add a new product to this category"
                              Icon="page-add-page" PermissionTypes="add" Location="Add"
                              WorkflowType="C1WorkflowDemo.Workflows.AddNewProductWorkflow, C1WorkflowDemo" />            
            </Actions>
           <OrderBy>
              <Field FieldName="Name"/>
            </OrderBy>
            <Children>
              <DataElements Type="C1WorkflowDemo.DataTypes.IProduct" Icon="page">
                <Filters>
                  <ParentIdFilter ParentType="C1WorkflowDemo.DataTypes.IProductCategory" ReferenceFieldName="ProductCategoryId"/>
                </Filters>
                <Actions>
                  <WorkflowAction Label="Edit"
                                  ToolTip="Edit this product"
                                  Icon="page-edit-page" PermissionTypes="edit" Location="Edit"
                                  WorkflowType="C1WorkflowDemo.Workflows.EditProductWorkflow,C1WorkflowDemo" />
                  <WorkflowAction Label="Delete"
                                  ToolTip="Delete this product"
                                  Icon="page-delete-page" PermissionTypes="delete" Location="Delete"
                                  WorkflowType="C1WorkflowDemo.Workflows.DeleteProductWorkflow,C1WorkflowDemo" />
                </Actions>
              </DataElements>
            </Children>
          </DataElements>
        </Children>      
      </Element>    
    </Children>
  </ElementRoot>
</ElementStructure>

...Мы же посмотрим, как добавляются "рабочие потоки".

Любое действие, в т.ч. и "рабочий поток" привязываются к элементам, к которым они относятся - и добавляются внутри элемента Actions.

Рабочий поток добавляется при помощи элемента WorkflowAction.

У него два обязательных атрибута:
  • WorkflowType: Тип рабочего потока (указывается как "[тип, включая пространства имен], [название сборки]" - напр.: "C1WorkflowDemo.Workflows.AddNewProductWorkflow, C1WorkflowDemo")
  • Label: Подпись (ярлык) для кнопки на панели инструментов - для вызова этого действия.
И четыре не обязательных:
  • Tooltip: Всплывающая подсказка для этого действия
  • Icon: Иконка для этого действия
  • PermissionTypes: Список разрешений на это действие
  • Location: Расположение кнопки вызова этого действия на панели инструментов.

<Actions>
  <WorkflowAction
    Label="Добавить продукт..."
    ToolTip="Добавить новый продукт в эту категорию"
    Icon="page-add-page"
    PermissionTypes="add"
    Location="Add"
    WorkflowType="C1WorkflowDemo.Workflows.AddNewProductWorkflow, C1WorkflowDemo" />
</Actions>

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

В следующем сообщении мы обсудим использование другого пользовательского действия: открытия ASPX страниц в админке.

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

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