Desktop e ModularBr

Simplificando a utilização do ModularBr com o aplicações desktop através de middleware.

O ModularBr é um framework versátil, além de sua integração com o frameworks Rest para construção de APIs RESTful, o ModularBr também é adequado para o desenvolvimento de projetos client/server (desktop). Com suas funcionalidades de injeção de dependência e exportação de binds, o ModularBr oferece uma abordagem modular para o desenvolvimento de aplicações em Delphi. Essa abordagem pode ser aplicada a projetos que envolvem a comunicação entre cliente e servidor, permitindo que o desenvolvedor se beneficie da modularidade, reutilização de código e gerenciamento de dependências oferecidos pelo ModularBr. Ao adotar o ModularBr em projetos client/server, os desenvolvedores podem melhorar a organização do código, facilitar a manutenção e promover a escalabilidade das aplicações desktop.

Assim como ocorre nas aplicações RESTful, nas aplicações desktop, o AppModule também desempenha um papel fundamental como ponto de entrada para a utilização do ModularBr.

uses
  dmfbr.modular,
...

procedure TFormPing.PingClick(Sender: TObject);
var
  LRouteHandler: TPingRouteHandler;
begin
  LRouteHandler := TPingRouteHandler.Create;
  try
    ShowMessage(LRouteHandler.Ping);
  finally
    LRouteHandler.Free;
  end;
end;

procedure TFormPing.FormCreate(Sender: TObject);
begin
  Modular.Start(TAppModule.Create);
end;

No AppModule, definimos as rotas iniciais.

...
function TAppModule.Routes: TRoutes;
begin
  Result := [RouteModule('/ping', TPingModule)];
end;

Definimos então o modulo da rota mapeada '/ping'

unit ping.module;

interface

uses
  ping.controller,
  ping.service,
  dmfbr.module;

type
  TPingModule = class(TModule)
  public
    function Imports: TImports; override;
    function Binds: TBinds; override;
    function Routes: TRoutes; override;
    function RouteHandlers: TRouteHandlers; override;
    function ExportedBinds: TExportedBinds; override;
  end;

implementation

{ TPingModule }

function TPingModule.Binds: TBinds;
begin
  Result := [Bind<TPingService>.Factory,
             Bind<TPingController>.Singleton];
end;
function TPingModule.ExportedBinds: TExportedBinds;
begin
  Result := [];
end;

function TPingModule.Imports: TImports;
begin
  Result := [];
end;

function TPingModule.RouteHandlers: TRouteHandlers;
begin
  Result := [];
end;

function TPingModule.Routes: TRoutes;
begin
  Result := [];
end;

end.

Os Route Handlers, ou manipuladores de rotas, são responsáveis por invocar os módulos desejados, de acordo com as rotas definidas no AppModule.

unit ping.route.handler;

interface

uses
  SysUtils,
  result.pair,
  dmfbr.modular,
  ping.controller,
  dmfbr.route.handler;

type
  TPingRouteHandler = class(TRouteHandler)
  protected
    procedure RegisterRoutes; override;
  public
    function Ping: string;
  end;

implementation

uses
  dmfbr.route.abstract;

{ TPingRouteHandler }

procedure TPingRouteHandler.RegisterRoutes;
begin

end;

function TPingRouteHandler.Ping: string;
var
  LResultPing: string;
  LResultRoute: TResultPair<Exception, TRouteAbstract>;
begin
  LResultPing := '';
  LResultRoute := Modular.LoadRouteModule('/ping');
  try
    LResultRoute.TryException(
      procedure (Error: Exception)
      begin
        // Failure
        LResultPing := Error.Message;
        Error.Free;
      end,
      procedure (Route: TRouteAbstract)
      begin
        // Success
        LResultPing := Modular.Get<TPingController>.Ping;
      end);
   finally
     Modular.DisposeRouteModule('/ping');
   end;
  Result := LResultPing;
end;

end.

A partir deste ponto em diante, a escolha do padrão a ser adotado é completamente sua. O ModularBr proporciona total liberdade e flexibilidade para que você decida qual padrão deseja utilizar. Nesta documentação, apresentaremos um exemplo utilizando os conceitos de controller e service, seguindo o princípio de responsabilidade única, com o intuito de ilustrar a implementação. Contudo, é importante ressaltar que você tem a opção de escolher outros padrões, de acordo com suas necessidades e preferências individuais.

O Controller

unit ping.controller;

interface

uses
  ping.service;

type
  TPingController = class
  private
    FService: TPingService;
  public
    constructor Create(const AService: TPingService);
    destructor Destroy; override;
    function Ping: string;
  end;

implementation

{ TPingController }

constructor TPingController.Create(const AService: TPingService);
begin
  FService := AService;
end;

destructor TPingController.Destroy;
begin
  FService.Free;
  inherited;
end;

function TPingController.Ping: String;
begin
  Result := FService.Ping;
end;

end.

O Service

unit ping.service;

interface

type
  TPingService = class
  public
    function Ping: string;
  end;

implementation

{ TPingService }

function TPingService.Ping: string;
begin
  Result := 'Pong';
end;

end.

Last updated