SDK de Microsoft Information Protection: Observadores del SDK de directivas

El SDK de directivas contiene una clase de observador. Los miembros del observador son virtuales y se deben invalidar para controlar las devoluciones de llamada de las operaciones asincrónicas.

Cuando finaliza una operación asincrónica, se llama a la función miembro de OnXxx() correspondiente para obtener el resultado. Algunos ejemplos de ello son OnLoadSuccess(), OnLoadFailure() y OnAddEngineSuccess() para mip::Profile::Observer.

Los ejemplos siguientes muestran el patrón de promesa/futuro, que también se usa en los ejemplos del SDK, y se puede ampliar para implementar el comportamiento de devolución de llamada deseado.

Implementación del observador de perfil

En el ejemplo siguiente, hemos creado una clase, ProfileObserver, que se deriva de mip::Profile::Observer. Las funciones miembro se han invalidado para usar el patrón futuro/promesa usado en los ejemplos.

Nota: Los ejemplos siguientes solo se implementan parcialmente y no incluyen invalidaciones para los observadores de mip::ProfileEngine relacionados.

profile_observer.h

En el encabezado, definimos ProfileObserver, que deriva de mip::Profile::Observer, y, a continuación, invalidamos cada una de las funciones miembro.

class ProfileObserver final : public mip::Profile::Observer {
public:
ProfileObserver() { }
  void OnLoadSuccess(const std::shared_ptr<mip::Profile>& profile, const std::shared_ptr<void>& context) override;
  void OnLoadFailure(const std::exception_ptr& error, const std::shared_ptr<void>& context) override;
  //TODO: Implement remaining members
};

profile_observer.cpp

En la propia implementación, definimos la acción que se debe realizar para cada función miembro del observador.

Cada miembro acepta dos parámetros. El primero es un puntero compartido a la clase que controla la función. ProfileObserver::OnLoadSuccess esperaría recibir mip::Profile. ProfileObserver::OnAddEngineSuccess esperaría mip::ProfileEngine.

El segundo es un puntero compartido al contexto. En nuestra implementación, el contexto es una referencia a std::promise que se ha enviado como shared_ptr<void>. La primera línea de la función convierte todo esto en std::promise y, a continuación, se almacena en un objeto denominado promise.

Por último, se prepara el futuro estableciendo el valor de promise->set_value() y pasando el objeto mip::Profile.

#include "profile_observer.h"
#include <future>

//Called when Profile is successfully loaded
void ProfileObserver::OnLoadSuccess(const std::shared_ptr<mip::Profile>& profile, const std::shared_ptr<void>& context) {
  //cast context to promise
  auto promise = std::static_pointer_cast<std::promise<std::shared_ptr<mip::Profile>>>(context);
  //set promise value to profile
  promise->set_value(profile);
}

//Called when Profile fails to load
void ProfileObserver::OnLoadFailure(const std::exception_ptr& error, const std::shared_ptr<void>& context) {
  auto promise = std::static_pointer_cast<std::promise<std::shared_ptr<mip::Profile>>>(context);
  promise->set_exception(error);
}

//TODO: Implement remaining observer members

Al realizar cualquier operación asincrónica, la implementación del observador se pasa al constructor de configuración o a la propia función asincrónica.