
Product
Announcing Precomputed Reachability Analysis in Socket
Socket’s precomputed reachability slashes false positives by flagging up to 80% of vulnerabilities as irrelevant, with no setup and instant results.
@arcmantle/injector
Advanced tools
Dependency injection done simple.
A lightweight, type-safe dependency injection container for TypeScript/JavaScript applications with support for multiple binding types, lifetimes, and hierarchical containers.
npm install @arcmantle/injector
# or
pnpm add @arcmantle/injector
# or
yarn add @arcmantle/injector
import { PluginContainer } from '@arcmantle/injector';
const container = new PluginContainer();
// Bind a constant value
container.bind('API_URL').constant('https://api.example.com');
container.bind('config').constant({ timeout: 5000, retries: 3 });
class DatabaseService {
constructor(private container: PluginContainer) {}
}
class UserService {
constructor(private container: PluginContainer) {
this.db = container.get('database');
}
}
// Bind classes (singleton by default)
container.bind('database').class(DatabaseService).singleton();
container.bind('users').class(UserService).transient();
// Bind a factory function
container.bind('logger').factory(container => {
const config = container.get('config');
return new Logger(config.logLevel);
}).singleton();
// Get a single instance
const config = container.get('config');
const userService = container.get<UserService>('users');
// Try to get (returns undefined if not bound)
const optional = container.tryGet('optional-service');
// Get all instances of a binding
const plugins = container.getAll('plugin');
// Bind multiple implementations with names
container.bind('database').class(PostgreSQLService).named('postgres');
container.bind('database').class(MongoDBService).named('mongo');
// Resolve by name
const pgDb = container.getNamed('database', 'postgres');
const mongoDb = container.getNamed('database', 'mongo');
// Bind with name and tag for extra specificity
container.bind('cache')
.class(RedisCache)
.tagged('redis', 'production');
container.bind('cache')
.class(MemoryCache)
.tagged('memory', 'development');
// Resolve by name and tag
const prodCache = container.getTagged('cache', 'redis', 'production');
container.bind('service')
.class(MyService)
.onActivation((instance, container) => {
// Perform additional setup
instance.initialize();
return instance;
})
.singleton();
const parentContainer = new PluginContainer();
const childContainer = new PluginContainer({ parent: parentContainer });
// Child containers inherit parent bindings
parentContainer.bind('shared').constant('parent-value');
console.log(childContainer.get('shared')); // 'parent-value'
// Child bindings override parent bindings
childContainer.bind('shared').constant('child-value');
console.log(childContainer.get('shared')); // 'child-value'
import { PluginModule } from '@arcmantle/injector';
// Create a module
const databaseModule = new PluginModule(({ bind, bindOnce, rebind }) => {
bind('connection').factory(container => {
const config = container.get('db-config');
return new Connection(config);
}).singleton();
bind('repository').class(UserRepository).transient();
});
// Load the module
container.load(databaseModule);
// Unload when needed
container.unload(databaseModule);
bind(identifier)
Creates a new binding, potentially overriding existing ones.
bindOnce(identifier)
Only binds if the identifier doesn't already exist. Returns undefined
if already bound.
rebind(identifier)
Removes existing bindings for the identifier and creates a new one.
Method | Description |
---|---|
get(id) | Get single instance (throws if not found) |
tryGet(id) | Get single instance or undefined |
getNamed(id, name) | Get named instance |
getTagged(id, name, tag) | Get tagged instance |
getAll(id) | Get all instances as array |
tryGetAll(id) | Get all instances or empty array |
getLast(id) | Get the last registered instance |
// Check if bindings exist
container.has('service'); // In this container only
container.exists('service'); // In this container or parents
container.hasNamed('service', 'name');
container.existsNamed('service', 'name');
// Remove bindings
container.unbind('service'); // Remove specific binding
container.unbindAll(); // Remove all bindings
The library is designed with TypeScript in mind:
interface IUserService {
getUser(id: string): User;
}
class UserService implements IUserService {
getUser(id: string): User {
// implementation
}
}
// Type-safe binding and resolution
container.bind<IUserService>('users').class(UserService);
const userService = container.get<IUserService>('users');
const container = new PluginContainer({
defaultLifetime: 'transient', // Default: 'singleton'
parent: parentContainer // Optional parent container
});
Apache-2.0 © Kristoffer Roen-Lie
This package is part of the @arcmantle monorepo. Please refer to the main repository for contribution guidelines.
FAQs
Dependency injection done simple.
We found that @arcmantle/injector demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Product
Socket’s precomputed reachability slashes false positives by flagging up to 80% of vulnerabilities as irrelevant, with no setup and instant results.
Product
Socket is launching experimental protection for Chrome extensions, scanning for malware and risky permissions to prevent silent supply chain attacks.
Product
Add secure dependency scanning to Claude Desktop with Socket MCP, a one-click extension that keeps your coding conversations safe from malicious packages.