Создание серверного модуля для приложения

Перед созданием модуля ознакомьтесь со страницей Создание модуля для приложения.

Основы взаимодействия модуля и основной конфигурации

Для начала необходимо объяснить, что же такое модуль и как он должен взаимодействовать с основной конфигурацией (платформой и ядром) приложения. Модуль – это отделяемая часть бизнес логики приложения, использующая возможности ядра и платформы для интеграции с другими модулями и с платформой системы. Другими словами, модуль – значительный блок логики и данных в контексте всего приложения. Взаимодействие модуля и других частей конфигурации происходит на 3-х уровнях:

  • Модель данных – на этом уровне можно создавать собственные модели, расширять и наследовать уже существующие в других частях;
  • Точки расширения – через этот механизм происходит основная часть интеграции в приложение, тут вы просто реализуете определенные интерфейсы и получаете требуемый функционал;
  • События – простая событийная модель позволяет осуществлять еще более глубокую интеграцию.

Сам по себе модуль, обычно, представляет набор библиотек и веб-приложение для отображения данных. Модули могут быть самыми разными, от простых кусочков интеграции (например, интеграция модуля задач и модуля документов), до сложных самостоятельных модулей (например, модуль Управления проектами).

Создание модуля

Для создания модуля можно использовать Visual Studio 2010/2013/2015/2017 и плагин для разработки ELMA. Структура модуля одинакова для той и другой версии VS. Примеры сделаны в 2013 версии.

Чтобы создать модуль, нужно открыть VS – Создать проект (New Project) – Модуль для системы ELMA3.

Результатом создания будет решение с двумя проектами:

где EleWise.ELMA.CRMExtension – серверная часть модуля, а EleWise.ELMA.CRMExtension.Web – веб-часть модуля.

Файл AssemblyInfo.md теперь создается сразу. Он находится в серверной части модуля. Здесь вы можете задать необходимые Вам отображаемой имя, описание и т.д.

Создание и подготовка модели данных

Перед созданием полей по умолчанию необходимо в проект добавить сборку EleWise.ELMA.Security.

После всех приготовлений мы получаем проект, в котором можно добавлять новые модели и расширять существующие. В нашем примере, мы создадим модуль Работа с клиентами, в котором будет отображаться список компаний, будет возможность создавать\изменять компании. Также будет возможность прикреплять к компании документ и файл с комментарием. У компании будут поля:

  • Наименование;
  • Дата создания;
  • Дата изменения;
  • Автор создания;
  • Автор изменения;
  • ИНН;
  • КПП.

Для демонстрации этих полей будет достаточно. Сначала добавим новую сущность в папку Models, назовем ее Company и добавим в нее свойства по умолчанию: Наименование, Автор создания, Автор изменения, Дата создания, Дата изменения. Для создания сущности нажимаем правой кнопкой мыши по папке Models AddNew ItemELMA Entity Interface.

Свойства Наименование, Автор и Дата создания необходимо отметить как обязательные для заполнения. Добавим свойства ИНН и КПП строкового типа. Для объекта Company нужно установить флажок Генерировать фильтр.

Подготовка бизнес логики

Вся бизнес логика приложения должна быть вынесена в специальные классы-менеджеры. Создадим свой класс-менеджер для работы с Компаниями:

public class CompanyManager : EntityManager<ICompany, long>

Обратите внимание, ICompany – это интерфейс. При создании сущности в Дизайнере на самом деле генерируется интерфейс, на основе свойств, добавленных в сущность. Второй параметр – это тип идентификатора сущности, он по умолчанию long, но это можно изменить при необходимости. Базовый класс EntityManager уже содержит необходимые методы для создания, сохранения, загрузки и удаления сущности. Особое внимание необходимо уделить тому, как создаются новые экземпляры сущности. Поскольку мы работаем с интерфейсами, то создавать напрямую объекты мы не можем, но есть два способа сделать это быстро и правильно:

  1. Вызвать метод Create() в менеджере.
  2. Использовать методы Create() класса EleWise.ELMA.Model.Services.InterfaceActivator.

На самом деле в первом случае делается перевызов второго варианта. В этом классе нужно определять любую логику работы с сущностями. В любом месте приложения будет доступен глобальный экземпляр вашего менеджера через статическое свойство Instance. Чтобы переопределить и возвращать сразу нужный тип менеджера, добавьте в ваш класс:

public new static CompanyManager Instance
        {
            get
            {
                return Locator.GetServiceNotNull<CompanyManager>();
            }
        }

В нашем модуле нам потребуется разграничивать права пользователей. У нас будет всего 2 уровня доступа:

  1. Доступ к модулю (глобально возможность видеть модуль).
  2. Возможность редактировать компанию (это право есть только у автора компании).

Первый – это глобальный уровень, он назначается ролям через интерфейс администрирования. Второй – это уровень доступа на сущность, он зависит от значения поля Автор сущности. Для создания этих уровней необходимо использовать точку расширения EleWise.ELMA.Security.Services.IPermissionProvider, в ней необходимо реализовать 2 функции и 3 свойства:

  • GetPermissions() – функция, возвращает набор готовых экземпляров класса EleWise.ELMA.Security.Permission;
  • GetPermissionStereotypes() – функция, возвращает набор предустановленных прав для этого модуля, они будут созданы при подключении модуля;
  • LocalizedItemsNames – свойство, возвращает локализированные имена привилегий;
  • LocalizedItemsDescriptions – свойство, возвращает локализированные описания привилегий;
  • LocalizedItemsCategories – свойство, возвращает локализированные имена категорий.

Более подробно смотрите страницы Настраиваемые привилегии на объекты и Привилегии. В нашем случае реализация довольно простая:

[Component]
 public class CRMExtensionPermissionProvider : IPermissionProvider
 {
  public const string Module = "EleWise.ELMA.CRMExtensions";

  public const string CRMAccessPermissionId = "1958FB0F-755E-4C03-B94A-694B6E80333B";
  public static readonly Permission CRMAccessPermission =
   new Permission(CRMAccessPermissionId,
       SR.T("Доступ к модулю"),
       "",
       SR.T("Работа с клиентами"),
       moduleUid: Module);

  public const string ViewCompanyPermissionId = "243C5DBA-ED64-4417-919A-2F20893F5017";
  public static readonly Permission ViewCompanyPermission =
   new Permission(ViewCompanyPermissionId,
       SR.T("Просмотр компании"),
       "",
       SR.T("Работа с клиентами"),
       moduleUid: Module, //Тут задается ключ для группировки по модулям
       permissionType: PermissionType.Instance, //Тип привилегии, в данном случае - на сущность
       @base: CommonPermissions.View, //Базовая привилегия
       entityType: InterfaceActivator.TypeOf<ICompany>()); //Тип сущности для данной привилегии


  public IEnumerable<Permission> GetPermissions()
  {
   return new[] { CRMAccessPermission, ViewCompanyPermission };
  }

  public IEnumerable<PermissionStereotype> GetPermissionStereotypes()
  {
   return new[]
   {
    new PermissionStereotype(new[]
    {
     CRMAccessPermission,
     ViewCompanyPermission
    }, SecurityConstants.AllUsersGroupDescriptor), 
   };
  }

  public List<string> LocalizedItemsNames
  {
   get
   {
    return new List<string>
    {
     SR.T("Доступ к модулю"),
     SR.T("Просмотр компании")
    };
   }
  }

  public List<string> LocalizedItemsDescriptions
  {
   get
   {
    return new List<string>
    {
     SR.T("Пользователи, обладающие этой привилегией, могут редактировать структуру дерева общих фильтров. Для предоставление полного доступа ко всем фильтрам необходимо дабавить глобальную привилегию \"Доступ ко всем фильтрам\"")
    };
   }
  }

  public List<string> LocalizedItemsCategories
  {
   get
   {
    return new List<string>
    {
     SR.T("Работа с клиентами")
    };
   }
  }
 }

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

Можно переходить к созданию веб-модуля.

Примечание
При создании серверного модуля созданную библиотеку необходимо выложить в папку bin веб-сайта, а именно добавить библиотеку в каталог <ELMA>\Web\bin, после чего необходимо перезапустить сервер.
Для включения созданного модуля в веб-части системы перейдите на вкладку Администрирование – Система – Компоненты. После этого необходимо перейти в группу Доступные. Среди доступных компонентов найдите Ваш модуль и включите его. После этого сервер будет перезапущен.