一键导入
horse-dependency-injection
Guide for managing request-scoped contextual services and IoC (dependency injection) in Delphi and Lazarus.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Guide for managing request-scoped contextual services and IoC (dependency injection) in Delphi and Lazarus.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
Guidelines and workflows for developing and maintaining regular expressions and optional parameter routing features in the Horse framework.
Guidelines for registering, executing, and optimizing native high-precision telemetry hooks (AddOnTelemetry) in the Horse Web Framework.
Guidelines for instantiating and configuring independent Horse server instances (THorseInstance) running concurrently on different ports.
Guide for setting up thread-safe database connection pooling (FireDAC / UniDAC) in multithreaded Horse applications.
Guide to using standard Horse middlewares (CORS, Jhonson, compression, basic-auth, logger) and pipeline registration order.
Guidelines for setting up endpoints, defining path parameters, route wildcards, and structuring HTTP controllers.
| name | horse-dependency-injection |
| description | Guide for managing request-scoped contextual services and IoC (dependency injection) in Delphi and Lazarus. |
The Services property in THorseRequest provides a thread-safe, request-scoped Inversion of Control (IoC) container. This container manages the lifecycle of classes and objects that need to exist only during the execution of a single HTTP request (e.g., database connections, repository patterns, user context).
doOwnsValues := True) of registered instances.try/finally blocks inside route handlers.Add)Use Add to register an already instantiated object. The container takes ownership and will destroy the instance when the request ends.
procedure SetContextMiddleware(Req: THorseRequest; Res: THorseResponse; Next: TProc);
var
LUserContext: TUserContext;
begin
LUserContext := TUserContext.Create;
LUserContext.UserId := Req.Headers['X-User-ID'];
// Register the instance
Req.Services.Add(TUserContext, LUserContext);
Next();
end;
procedure GetProfileHandler(Req: THorseRequest; Res: THorseResponse; Next: TProc);
var
LUserContext: TUserContext;
begin
// Resolve and use the registered service
LUserContext := TUserContext(Req.Services.Resolve(TUserContext));
Res.Send('Profile data for user: ' + LUserContext.UserId);
end;
AddFactory)Use AddFactory to register a factory delegate. The object will only be instantiated at the exact moment Resolve is called (Lazy Loading). Once instantiated, it is cached for subsequent resolves in the same request and destroyed at the end.
This is highly recommended for heavy resources (like database connections) that might not be needed in every execution path of a route.
procedure RegisterDatabaseMiddleware(Req: THorseRequest; Res: THorseResponse; Next: TProc);
begin
// Register the factory method
Req.Services.AddFactory(TFDConnection,
function: TObject
begin
Result := TFDConnection.Create(nil);
TFDConnection(Result).ConnectionDefName := 'PooledPGDef';
TFDConnection(Result).Connected := True;
end);
Next();
end;
procedure QueryUsersHandler(Req: THorseRequest; Res: THorseResponse; Next: TProc);
var
LConnection: TFDConnection;
LQuery: TFDQuery;
begin
// The connection is physically created and opened only on the next line!
LConnection := TFDConnection(Req.Services.Resolve(TFDConnection));
LQuery := TFDQuery.Create(nil);
try
LQuery.Connection := LConnection;
LQuery.SQL.Text := 'SELECT id, name FROM users';
LQuery.Open;
Res.Send(LQuery.ToJSONArray);
finally
LQuery.Free;
end; // LConnection is automatically freed by the container when the request ends!
end;
Services container belongs exclusively to the thread handling the current THorseRequest.Resolve method returns a raw TObject to preserve compatibility across old Delphi versions. You must cast it to your concrete class (e.g., TMyService(Req.Services.Resolve(TMyService)))..Free or FreeAndNil on objects resolved from Req.Services that you want to persist until the end of the request.