Punkty rozszerzeń (POS extension points)

Moduł Comarch.POS.ExtensionPoints umożliwia wielokrotne rozszerzenie tej samej metody viewmodelu. W ten sposób można tworzyć wiele niezależnych od siebie rozszerzeń, które modyfikują działanie tej samej funkcji natywnej.

Architektura punktów rozszerzeń

Dla rozszerzanego viewmodelu został stworzony dodatkowy viewmodel dziedziczący, a dla niego dedykowany serwis biznesowy. Przykładowo:

public class DocumentViewModelExtensionPoint : DocumentViewModel

public class DocumentViewModelExtensionPointService :

  PrintingViewModelNavigationExtensionPointService<IDocumentViewModel>,

  IDocumentViewModelExtensionPointService

  IDocumentViewModelExtensionPointInternalService

Każda rozszerzana metoda viewmodelu posiada w serwisie dwa eventy „do wpięcia”: Before oraz After. Wyjątek stanowią aktywatory, czyli metody które zwracają flagę boolean. Dla nich istnieje tylko jeden event.

Rozszerzając konkretną metodę viewmodelu uzyskujemy dostęp zarówno do parametrów danego wywołania jak również do instancji danego viewmodelu. Celem jest udostepnienie pełnego kontekstu działania.

!!Uwaga!!

Event Before<nazwa_metody> umożliwia sygnalizowanie przerwania wywołania standardowego wywołania. Należy pamiętać ze w środowisku wielodoróbkowym pod ten sam event może być zapiętych wiele rozszerzeń. Każde kolejne wywołanie będzie bazować na rezultacie poprzedniego. Nie można zakładać ze na początku wywołania wartość Cancel będzie ustawiona na false. Dodatkowo należy założyć ze kolejność wywołania rozszerzeń jest niedeterministyczna.

Przykład:

[Dependency]
public IPaymentViewModelExtensionPointService PaymentViewModelExtensionPointService
{ get; set; }

public override void Initialize()
{
   PaymentViewModelExtensionPointService.BeforeAddToPaymentFormEvent +=
_paymentViewModelExtensionPointService_BeforeAddToPaymentFormEvent;
}

private void _paymentViewModelExtensionPointService_BeforeAddToPaymentFormEvent(object sender, EntityViewModelCancelEventArgs<IPaymentViewModel, PaymentFormRow> e)
{
            if (e.Cancel) // obsluga stanu wejsciowego
                return;

            // kod
        }

Wywołanie natywnej metody ViewModelu

Może się zdarzyć sytuacja, gdy w ramach rozszerzenia chcemy uzależnić wywołanie natywnej operacji od decyzji operatora. Komunikaty na POS nie są blokujące, zatem obsługę można kontynuować tylko w handlerze zwrotnym z okna komunikatu.

private void _documentViewModelExtensionPointService_BeforeProductAddEvent(object sender, EntityViewModelCancelEventArgs<IDocumentViewModel, LotRow> e) {




   e.Cancel = true;




   MonitService.ShowQuestion("Czy dodać towar?", (s, m) => {

       if (m.MonitResult == MonitResult.Yes) {

           var serv = DocumentViewModelExtensionPointService.

GetViewModelActions(e.ViewModel);

           serv.ProductAdd(e.EntityRow);

       }

   });

}

Metoda GetViewModelActions zwraca nam instancje, która umożliwia wywoływanie natywnych metod bazowego viewModelu z pominięciem rozszerzalności.

Dostępne punkty rozszerzeń

Standardowo każde rozszerzenie viewmodelu daje możliwość modyfikacji metod nawigujących:

  • OnActivated() – BeforeOnActivatedEvent, AfterOnActivatedEvent
  • OnInitialization() – Before OnInitializationEvent, AfterOnInitializationEvent
  • OnDeactivated() – BeforeOnDeactivatedEvent, AfterOnDeactivatedEvent

Viewmodele, które obsługują proces wydruków posiadają dodatkowo rozszerzenia do metod:

  • Print() – BeforePrintEvent, AfterPrintEvent
  • CanPrint() – CanPrintEvent

Przykład implementacji

Poniżej znajduje się implementacja gotowego rozszerzenia, które pokaże dwa komunikaty w momencie zapisu dokumentu handlowego, jeden przed zapisem, drugi zaraz po.

using Microsoft.Practices.Unity;

using Comarch.POS.ExtensionPoints.Presentation.Sales.ViewModels;

using Comarch.POS.Presentation.Core.Services;

using Comarch.POS.Presentation.Core;




public class Module : ModuleBase

{

   private readonly IUnityContainer _container;

       

   [Dependency]

   public IMonitService MonitService { get; set; }




   [Dependency]

   public IDocumentViewModelExtensionPointService DocumentViewModelExtensionPointService { get; set; }

   public Module(IUnityContainer container) : base(container)

   {

      _container = container;

   }




   public override void Initialize()

   {

      DocumentViewModelExtensionPointService.BeforeSaveEvent += _documentViewModelExtensionPointService_BeforeSaveEvent;

      DocumentViewModelExtensionPointService.AfterSaveEvent += _documentViewModelExtensionPointService_AfterSaveEvent;

   }




   private void _documentViewModelExtensionPointService_AfterSaveEvent(object sender, GenerateViewModelEventArgs<IDocumentViewModel> e) {

      MonitService.ShowInformation("Extension: after save");

   }




   private void _documentViewModelExtensionPointService_BeforeSaveEvent(object sender, GenerateEntityViewModelCancelEventArgs<IDocumentViewModel> e) {

      if (e.Cancel)

         return;




      MonitService.ShowInformation("Extension: before save");

   } 

}

Czy ten artykuł był pomocny?