Repository navigation
servicos
Home > Serviços (contêiner de dependências) 🚧
Important
Em desenvolvimento (2.0). Ainda não está numa versão lançada e pode mudar.
Vale para a 2.0 · Delphi XE em diante e Lazarus/FPC 3.2 em diante · Nível: intermediário
Em uma frase: o TRALServiceContainer guarda, no Object Inspector, qual classe faz
cada serviço da aplicação (o envio de e-mail, o repositório de clientes) e quanto tempo
cada instância vive; o handler da rota pede o serviço ao contêiner em vez de criar e
liberar objetos à mão.
Você vai precisar: o pacote RALHostingContainerPackage (só requer PascalRAL).
type
IMailer = interface
['{0B2F6A51-3C4D-4E7F-8A9B-1C2D3E4F5A6B}']
procedure Send(const ATo, AText: string);
end;
TMailer = class(TRALService, IMailer)
public
procedure Send(const ATo, AText: string);
end;
initialization
RALRegisterService(TMailer); // o contêiner acha a classe pelo nome- Uma classe de serviço descende de
TRALService(contada por referência, use pela interface) ou deTComponent. O construtor deTRALServicerecebe o contêiner e o pedido, e pode pedir os serviços de que depende. -
RALRegisterServicetorna a classe conhecida pelo nome; quem não quer registrar cria a instância no eventoOnCreatedo item (ouOnCreateServicedo contêiner).
No Object Inspector, em Services, um item por serviço:
| propriedade | o que é |
|---|---|
Name |
o nome pelo qual o serviço é pedido (mailer) |
ServiceClass |
a classe registrada (TMailer) |
InterfaceGUID |
a interface pela qual ele também é pedido |
Lifetime |
slSingleton (uma só, a primeira vez que é pedida), slPerRequest (uma por pedido HTTP, liberada no fim dele) ou slTransient (nova a cada vez) |
procedure TForm1.RotaPedido(ARequest: TRALRequest; AResponse: TRALResponse);
var
vMailer: IMailer;
begin
Servicos.Resolve(IMailer, vMailer, ARequest); // pela interface
// ou: vMailer := Servicos.Resolve('mailer', ARequest) as IMailer;
// ou, com genéricos: vMailer := Servicos.ResolveAs<IMailer>(ARequest);
vMailer.Send('cliente@exemplo.com', 'Pedido recebido');
end;- Passe o
ARequestdo handler: um serviçoslPerRequesté o mesmo em todo o pedido (no handler e nos serviços que dependem dele) e é liberado quando o servidor termina o pedido. Pedido fora de um pedido HTTP, ele dá erro. - Um singleton é criado uma única vez mesmo com várias threads pedindo ao mesmo tempo, e
é liberado com o contêiner (ou em
Reset). - Um serviço que não é
TRALService(umTComponent) é pedido comResolveObject: singleton e por pedido são do contêiner; um transiente é de quem pediu, que libera. - Serviços que se pedem em círculo dão erro em vez de travar o programa.
Onde o compilador tem atributos e RTTI estendida, ponha RALServiceInject no uses e
marque os campos:
uses RALServiceContainer, RALServiceInject;
type
TPedidos = class(TRALService, IPedidos)
private
[Inject] FMailer: IMailer; // pela interface do campo
[Inject('clientes')] FClientes: IRepositorio;
...Os campos são preenchidos logo depois do construtor: use-os nos métodos, não no construtor. No Lazarus/FPC 3.2 a unit fica vazia; o construtor pede ao contêiner.
| sintoma | causa | o que fazer |
|---|---|---|
| "A classe ... não está registrada" | falta RALRegisterService
|
registre na initialization da unit da classe |
| "vive por pedido e foi pedido fora de um" |
slPerRequest sem o ARequest
|
passe o pedido do handler, ou mude o Lifetime
|
| "não tem interface: use ResolveObject" |
Resolve de um TComponent
|
ResolveObject |
| o objeto some logo depois de pedido |
TRALService guardado só como objeto |
guarde a interface |
Começar
Servidor
- Rotas e parâmetros
- Rotas avançadas: tipos, grupos, versões 🚧
- Ler o pedido e responder
- Objetos no corpo 🚧
- Resposta em fluxo 🚧
- Plugins 🚧
- Serviços (contêiner de dependências) 🚧
- Autenticação
- Banco de dados (DBWare)
- Servir site e arquivos
- JSON-RPC 2.0 🚧
- Servidor MCP (IA) 🚧
-
Protocol Buffers 🚧
- gRPC 🚧
- WebSocket 🚧
- Hubs (WebSocket) 🚧
- Swagger e Postman
- Servidor SOAP 🚧
- WS-Security 🚧
- HTTPS
- Criptografia ponto a ponto
- Segurança para produção
- Colocar no ar
- Desempenho
- Testes em memória 🚧
MQTT 🚧
- O que é e quando usar 🚧
- Cliente MQTT 🚧
- Broker MQTT 🚧
- MQTT-SN 🚧
- Ponte REST 🚧
- Segurança 🚧
- Rede ruim 🚧
E-mail 🚧
- Mensagens 🚧
- Enviar 🚧
- Receber 🚧
- Ler a caixa postal 🚧
- Verificar o que chega 🚧
- Servir caixas postais 🚧
- S/MIME 🚧
- OpenPGP 🚧
Chatbot 🚧
- O robô e os canais 🚧
- Telegram 🚧
- Gateways REST (WhatsApp não oficial) 🚧
- Discord 🚧
- Slack 🚧
- Microsoft Teams 🚧
- Conversa em etapas 🚧
Cliente
Motores
- Qual motor escolher?
- Compatibilidade
- Recursos
- QUIC
- Motor NgHttp2 (HTTP/2) 🚧
- Motor XSocket 🚧
- Motor AdvancedHTTP (experimental) 🚧
Avançado
Ajuda
- Problemas comuns
- Atualizar o Indy
- Várias versões do Delphi
- Vídeos e guias
- Módulos de terceiros
- Licenças
- Contribuir
- Roadmap e changelog
🚧 = em desenvolvimento, pode mudar