Обработчик Сообщений Сервера Xafari, который будет выполнять поиск файлов разместим в отдельном модуле.

Воспользуйтесь мастером DevExpress Solution Wizard и добавьте платформенно-независимый модуль в Solution. Назовите его FileSearcher. В качестве ORM укажите XPO.

Объявите 2 бизнес класса: для хранения исходных данных сообщения и хранения результатов. В примере использованы XPO, но с таким же успехом можно использовать и Domain Comonents.

 

[NavigationItem("Xafari Server Demo")]

public class SearchFiles : XPObject

{

    public const string Tag = "SearchFiles";

 

    public SearchFiles() {}

    public SearchFiles(Session session) : base(session) {}

 

    public string Path

    {

        get { return GetPropertyValue<string>("Path"); }

        set { SetDelayedPropertyValue("Path", value); }

    }

    public string SearchPattern

    {

        get { return GetPropertyValue<string>("SearchPattern"); }

        set { SetDelayedPropertyValue("SearchPattern", value); }

    }

    public long TotalSize

    {

        get { return GetPropertyValue<long>("TotalSize"); }

        set { SetDelayedPropertyValue("TotalSize", value); }

    }

    [Association, Aggregated]

    public XPCollection<FileInfo> Files

    {

        get { return GetCollection<FileInfo>("Files"); }

    }

}

 

public class FileInfo : XPObject

{

    public FileInfo(Session session) : base(session) {}

 

    [Association]

    public SearchFiles Owner

    {

        get { return GetPropertyValue<SearchFiles>("Owner"); }

        set { SetDelayedPropertyValue("Owner", value); }

    }

    public string FileName

    {

        get { return GetPropertyValue<string>("FileName"); }

        set { SetDelayedPropertyValue("FileName", value); }

    }

    public long Size

    {

        get { return GetPropertyValue<long>("Size"); }

        set { SetDelayedPropertyValue("Size", value); }

    }

}

 

Класс SearchFiles служит для хранения дополнительных данных Сообщения и хранения результатов обработки Сообщения. Константа SearchFiles.Tag будет служить идентификатором наших Сообщений.

Класс FileInfo будет хранить список найденных файлов.

Теперь нужно реализовать Обработчик Сообщений. В качестве базового класса Обработчика Сообщений удобно использовать абстрактный базовый класс Xafari.Server.MessageHanler. При реализации обработчика достаточно переопределить абстрактный метод ProcessMessageCore:

 

public class SearcFilesHandler : MessageHandler

{

    public SearcFilesHandler(XafApplication application, object messageKey) 

        : base(application, messageKey)

    {}

 

    protected override void ProcessMessageCore(

        IObjectSpace messageObjectSpace, 

        MQMessage message, CancellationToken token)

    {

        using (var objectSpace = Application.CreateObjectSpace())

        {

            var searchFiles = message.MessageData.SafeGetTargetObject<SearchFiles>(objectSpace);

            var directoryInfo = new DirectoryInfo(searchFiles.Path);

            long totalSize = 0;

            foreach (var file in directoryInfo.EnumerateFiles(searchFiles.SearchPattern))

            {

                token.ThrowIfCancellationRequested();

                

                var fileInfo = objectSpace.CreateObject<DemoApp.Module.BusinessObjects.FileInfo>();

                fileInfo.FileName = file.Name;

                fileInfo.Size = file.Length;

                searchFiles.Files.Add(fileInfo);

                totalSize += file.Length;

            }

            searchFiles.TotalSize = totalSize;

            objectSpace.CommitChanges();

        }

    }

}

 

Сервер Xafari выбирает необработанные Сообщения из Очереди и передает их Обработчику. Обработчик получает Сообщение в качестве параметра метода ProcessMessageCore. Дополнительные данные Сообщения (для наших сообщений это экземпляр объекта SearchFiles) хранятся в поле MQMessage.MessageData. Т.к. поле имеет тип XPWeakReferenceStruct, для получения объекта SearchFiles использован метод расширения Xafari.MQ. SafeGetTargetObject<T>. Объекты SearchFiles будем хранить в базе данных. Поэтому при получении объекта из XPWeakReferenceStruct указываем Object Space приложения. Само Сообщение (MQMessage) при этом может и не храниться в БД. Поэтому, для работы с самим Сообщением в качестве параметра метода ProcessMessageCore передается Object Space сообщения.

Экземпляр CancellationToken используется чтобы реализовать возможность прервать обработку Сообщения на сервере. Экземпляр CancellationToken передается в качестве параметра методу ProcessMessageCore. В приведенном Обработчике Сообщений в случае отмены сообщения будет сгенерировано исключение. Это исключение перехватывается в базовом классе MessageHandler и Сообщение переводится в статус «Error».

Далее Обработчик Сообщений следует зарегистрировать. Это выполняется в обработчике события XafApplication.SetupComplete в классе модуля FileSearcherModule:

 

public sealed partial class FileSearcherModule : ModuleBase {

    public override void Setup(XafApplication application) {

        base.Setup(application);

        Application.SetupComplete += Application_SetupComplete;

    }

 

    void Application_SetupComplete(object sender, EventArgs e)

    {

        XafariServerModule.DataObserver.ServerHandlersStrategy.

           RegisterHandler(

              SearchFiles.Tag, 

              (application, messageKey)=>

                 new SearcFilesHandler(application, messageKey));

    }

}

 

В качестве идентификатора сообщения указываем константу SearchFiles.Tag. Вторым параметром метода RegisterHandler передается делегат, который является фабрикой экземпляров Обработчиков Сообщений.