feat: add detailed JSDoc comments for injectServices and useService functions
This commit is contained in:
@@ -15,6 +15,40 @@ declare module 'hono' {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a Hono middleware that manages dependency injection service scopes for each request.
|
||||||
|
*
|
||||||
|
* This middleware creates a new service scope at the beginning of each request and automatically
|
||||||
|
* disposes of it when the request completes, ensuring proper resource cleanup and preventing
|
||||||
|
* memory leaks. The service scope is stored in the Hono context and can be accessed by subsequent
|
||||||
|
* middleware and route handlers.
|
||||||
|
*
|
||||||
|
* @param serviceProvider - The root service provider from which to create scoped instances
|
||||||
|
* @returns A Hono middleware handler that manages service scope lifecycle
|
||||||
|
*
|
||||||
|
* @example
|
||||||
|
* ```typescript
|
||||||
|
* import { Hono } from 'hono';
|
||||||
|
* import { injectServices, useService, ServiceCollection } from '@stevanfreeborn/hono-netdi';
|
||||||
|
*
|
||||||
|
* // Configure services
|
||||||
|
* const services = new ServiceCollection();
|
||||||
|
* services.addScoped(MyService);
|
||||||
|
* const serviceProvider = services.build();
|
||||||
|
*
|
||||||
|
* // Create Hono app with DI middleware
|
||||||
|
* const app = new Hono();
|
||||||
|
* app.use(injectServices(serviceProvider));
|
||||||
|
*
|
||||||
|
* app.get('/', (c) => {
|
||||||
|
* const myService = useService(c, MyService);
|
||||||
|
* return c.json({ data: myService.getData() });
|
||||||
|
* });
|
||||||
|
* ```
|
||||||
|
*
|
||||||
|
* @throws {Error} If the service provider is null or undefined
|
||||||
|
* @see {@link useService} for accessing services within request handlers
|
||||||
|
*/
|
||||||
export function injectServices(serviceProvider: IServiceProvider): MiddlewareHandler {
|
export function injectServices(serviceProvider: IServiceProvider): MiddlewareHandler {
|
||||||
return async (c: Context, next: () => Promise<void>) => {
|
return async (c: Context, next: () => Promise<void>) => {
|
||||||
const scope = serviceProvider.createScope();
|
const scope = serviceProvider.createScope();
|
||||||
@@ -29,6 +63,44 @@ export function injectServices(serviceProvider: IServiceProvider): MiddlewareHan
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves a service instance from the current request's dependency injection scope.
|
||||||
|
*
|
||||||
|
* This function extracts the service scope from the Hono context (which must have been
|
||||||
|
* set by the `injectServices` middleware) and uses it to resolve the requested service.
|
||||||
|
* Services are resolved according to their configured lifetime (singleton, scoped, or transient).
|
||||||
|
*
|
||||||
|
* @template T - The type of service to retrieve
|
||||||
|
* @param c - The Hono context containing the service scope
|
||||||
|
* @param serviceType - The service identifier used to resolve the service instance
|
||||||
|
* @returns The resolved service instance of type T
|
||||||
|
*
|
||||||
|
* @example
|
||||||
|
* ```typescript
|
||||||
|
* import { Context } from 'hono';
|
||||||
|
* import { useService, createServiceIdentifier } from '@stevanfreeborn/hono-netdi';
|
||||||
|
*
|
||||||
|
* interface IUserService {
|
||||||
|
* getUser(id: string): Promise<User>;
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* const userServiceId = createServiceIdentifier<IUserService>();
|
||||||
|
*
|
||||||
|
* app.get('/users/:id', async (c: Context) => {
|
||||||
|
* const userService = useService(c, userServiceId);
|
||||||
|
* const user = await userService.getUser(c.req.param('id'));
|
||||||
|
* return c.json(user);
|
||||||
|
* });
|
||||||
|
* ```
|
||||||
|
*
|
||||||
|
* @throws {Error} When the service scope is not found in the context (typically when
|
||||||
|
* `injectServices` middleware was not properly configured)
|
||||||
|
* @throws {Error} When the service scope is not a valid ServiceScope instance
|
||||||
|
* @throws {Error} When the requested service cannot be resolved (service not registered,
|
||||||
|
* missing dependencies, etc.)
|
||||||
|
*
|
||||||
|
* @see {@link injectServices} for setting up the dependency injection middleware
|
||||||
|
*/
|
||||||
export function useService<T>(c: Context, serviceType: ServiceIdentifier<T>): T {
|
export function useService<T>(c: Context, serviceType: ServiceIdentifier<T>): T {
|
||||||
const scope = c.get(SERVICE_SCOPE_KEY);
|
const scope = c.get(SERVICE_SCOPE_KEY);
|
||||||
|
|
||||||
@@ -44,3 +116,5 @@ export function useService<T>(c: Context, serviceType: ServiceIdentifier<T>): T
|
|||||||
|
|
||||||
return scope.serviceProvider.getService(serviceType);
|
return scope.serviceProvider.getService(serviceType);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export * from '@stevanfreeborn/netdi';
|
||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
import { describe, expect, test } from 'vitest';
|
import { describe, expect, test } from 'vitest';
|
||||||
import { Env, Hono } from 'hono';
|
import { Env, Hono } from 'hono';
|
||||||
import { createServiceIdentifier, IServiceScope, ServiceCollection } from '@stevanfreeborn/netdi';
|
import { createServiceIdentifier, IServiceScope, ServiceCollection } from '../src/index';
|
||||||
import { injectServices, useService } from '../src/index';
|
import { injectServices, useService } from '../src/index';
|
||||||
import { randomUUID } from 'crypto';
|
import { randomUUID } from 'crypto';
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user