DI Integration
The lockFactoryResolverDiFactory function creates an ILockFactoryResolver whose underlying resolver is resolved from a DI container.
The returned proxy implements both ILockFactoryResolver and ILockFactory:
use(adapterName?)selects an adapter on the resolvedLockFactoryResolver.create(key, settings?)creates a lock through the resolver's default adapter.
The proxy is wired to the container during container.init(). Create it before calling init(); calling use() or create() before the container is initialized throws an error.
Initial configuration
Set up the memory and Redis lock adapters, create the container, then register the LockFactoryResolver and wrap it with lockFactoryResolverDiFactory:
1. Set up the memory lock adapter
./samples/memory-lock-adapter.ts
import { MemoryLockAdapter } from "eridu-tech/lock/memory-lock-adapter";
export const memoryLockAdapter = new MemoryLockAdapter();
2. Set up the Redis lock adapter
./samples/redis-lock-adapter.ts
import { RedisLockAdapter } from "eridu-tech/lock/redis-lock-adapter";
import { Redis } from "ioredis";
export const redisLockAdapter = new RedisLockAdapter(
new Redis("YOUR_REDIS_CONNECTION_STRING"),
);
3. Create the dependency injection container
./samples/container.ts
import { Container } from "eridu-tech/di";
import { ExecutionContext } from "eridu-tech/execution-context";
import { AlsExecutionContextAdapter } from "eridu-tech/execution-context/als-execution-context-adapter";
export const executionContext = new ExecutionContext(
new AlsExecutionContextAdapter(),
);
export const container = new Container({ executionContext });
4. Register and initialize the lock factory resolver
./samples/lock-factory-resolver-di-factory.ts
import { LockFactoryResolver } from "eridu-tech/lock";
import { ProxyLockFactoryResolver } from "eridu-tech/lock/di";
import { container } from "./container.js";
import { memoryLockAdapter } from "./memory-lock-adapter.js";
import { redisLockAdapter } from "./redis-lock-adapter.js";
type Adapters = "memory" | "redis";
const lockFactoryResolver = new LockFactoryResolver<Adapters>({
adapters: {
memory: memoryLockAdapter,
redis: redisLockAdapter,
},
defaultAdapter: "memory",
});
await lockFactoryResolver.init();
container.registerValue({
token: LockFactoryResolver,
value: lockFactoryResolver,
});
// Create the proxy before container.init()
export const lockFactory = new ProxyLockFactoryResolver<Adapters>({
container,
resolverToken: LockFactoryResolver,
});
await container.init();
Usage
1. Using the default adapter
./samples/lock-factory-resolver-di-factory-default-adapter.ts
import { lockFactory } from "./lock-factory-resolver-di-factory.js";
// Uses the adapter configured as the default (memory)
await lockFactory.create("shared-resource").runOrFail(async () => {
// code to run
});
2. Specifying an adapter explicitly
./samples/lock-factory-resolver-di-factory-specific-adapter.ts
import { lockFactory } from "./lock-factory-resolver-di-factory.js";
// Uses the Redis adapter
await lockFactory
.use("redis")
.create("shared-resource")
.runOrFail(async () => {
// code to run
});
Using it with the middlewares
Because the proxy implements ILockFactoryResolver, it can be passed straight to the lock middleware factories:
./samples/lock-factory-resolver-di-factory-with-middleware.ts
import { withLockFactory } from "eridu-tech/lock/middlewares";
import { use } from "eridu-tech/middleware";
import { lockFactory } from "./lock-factory-resolver-di-factory.js";
const withLock = withLockFactory(lockFactory);
const processJob = async (jobId: string): Promise<void> => {
// ... process the job
};
const safeProcess = use(
processJob,
withLock.use("redis")({
key: ([jobId]) => `job:${jobId}`,
}),
);
await safeProcess("job-123");
Further information
For further information refer to eridu-tech/lock API docs.