@dcc-bs/dependency-injection.bs.js
v0.0.16
Published
A lightweight, type-safe dependency injection system for JavaScript/TypeScript applications, with built-in support for Nuxt.js.
Downloads
122
Readme
Dependency Injection
A lightweight, type-safe dependency injection system for JavaScript/TypeScript applications, with built-in support for Nuxt.js.
Features
- Type-safe dependency resolution and injection
- Automatic dependency detection through constructor parameters
- Circular dependency detection
- Topological sorting of dependencies for proper initialization order
- Built-in integration with Nuxt.js
- Easily register existing instances or have them created automatically
- Supports named services for more flexible registration
Installation
Add this line to your package.json dependencies. Replace #v1.0.0 with the desired version.
{
"dependencies": {
"@dcc-bs/dependency-injection.bs.js": "git+https://github.com/DCC-BS/dependency-injection.bs.js.git#v1.0.0",
}
}run npm install or yarn install to install the package.
# Using npm
npm
# Using yarn
yarn
# Using bun
bun installUsage
Basic Example
import { ServiceProviderBuilder } from '@dcc-bs/dependency-injection.bs.js';
// Define your services with injection keys
class DatabaseService {
static $injectKey = 'DatabaseService';
static $inject = []; // No dependencies
connect() {
console.log('Database connected');
}
}
class UserRepository {
static $injectKey = 'UserRepository';
static $inject = [DatabaseService.$injectKey]; // This service depends on DatabaseService
// to get services injected, the name of the constructor parameter need to macht the injectKey
constructor(private readonly databaseService: DatabaseService) {}
getUsers() {
// Uses the injected database service
this.db.connect();
return ['user1', 'user2'];
}
}
class UserService {
static $injectKey = 'UserService';
static $inject = ["UserRepository"]; // you can also simply provide the inject key as a string
constructor(private readonly userRepository: UserRepository) {}
getAllUsers() {
return this.userRepository.getUsers();
}
}
// Set up the service provider
const builder = new ServiceProviderBuilder();
// Register services
builder.register(DatabaseService);
builder.register(UserRepository);
builder.register(UserService);
// Build the service provider
const serviceProvider = builder.build();
// Resolve services
const userService = serviceProvider.resolve(UserService);
console.log(userService.getAllUsers()); // ['user1', 'user2']Registering Existing Instances
// Register an existing instance
const db = new DatabaseService();
builder.registerInstance(DatabaseService, db);
// Register a named instance
builder.registerInstance('config', { apiUrl: 'https://api.example.com' });Using with Nuxt.js
This package provides built-in Nuxt.js integration:
Register the module:
// nuxt.config.ts
export default defineNuxtConfig({
modules: ['@dcc-bs/dependency-injection.bs.js'],
});Create a plugin:
// plugins/service-registrant.ts
export default defineNuxtPlugin((nuxtApp) => {
const orchestrator = new ServiceOrchestrator();
// the setup will be lazily called the first time a
// service is resolved, ensuring services are created
// in the Vue component lifecycle or setup context.
orchestrator.setup((builder) => {
const logger = useLogger();
const { t } = useI18n(); // this needs to be created in the setup context
builder.registerInstance("translate", t);
builder.registerInstance("logger", logger);
builder.register(DatabaseService);
builder.register(UserRepository);
builder.register(UserService);
// Register a service factory, which allows creating instances with custom parameters
// you can mix injected services and custom parameters,
// but the injected services must be before the custom parameters in the factory function
builder.registerFactory("ServiceWithFactory", (injected1, param1, param2) => {
return new SomeService(injected1, param1, param2);
});
builder.registerFactoryAsync("AsyncService", async (injected1, param1, param2) => {
const result = await fetchSomeData(injected1, param1, param2);
return new AsyncService(result);
});
});
nuxtApp.provide("serviceOrchestrator", orchestrator);
});Use the plugin in a component or a composable:
<script lang="ts" setup>
// For resolving registered service types
const databaseService = useService(DatabaseService);
// For creating service instances with custom parameters
const customService = createService("ServiceWithFactory", param1, param2);
// For creating service instances asynchronously
const asyncService = await createServiceAsync("AsyncService", param1, param2);
</script>API Reference
ServiceProviderBuilder
The main class for registering and constructing services.
Methods
register<T>(target: ServiceType<T>): Register a service type for later instantiationregisterInstance<T>(target: ServiceType<T>, instance: T): Register an existing service instanceregisterNamedInstance<T>(name: string, instance: T): Register a named service instancebuild(): Build and return the service providergetDependencyGraph(): Get a map of service dependencies for debugging
IServiceProvider
Interface for resolving services from the container.
Methods
resolve<T>(target: ServiceType<T>): Resolve a service by its typeresolveNamed<T>(name: string): Resolve a service by its nameresolveFactory<T>(target: string, ...args: any): Create and resolve a service with custom parametersresolveFactoryAsync<T>(target: string, ...args: any): Asynchronously create and resolve a service
ServiceOrchestrator
Manages service providers for Nuxt.js integration.
Methods
setup(builderFactory): Set up the service orchestrator with a factory function to configure the service providergetProvider(): Get the service provider instance (creates it lazily if not yet created)
Nuxt.js Composables
Conveniences for using the dependency injection system in Nuxt.js applications.
useService<T>(target: ServiceType<T>): Resolve a service by its typecreateService<T>(target: string, ...args): Create and resolve a service with custom parameterscreateServiceAsync<T>(target: string, ...args): Asynchronously create and resolve a service
Advanced Usage
Visualizing Dependencies
const builder = new ServiceProviderBuilder();
// Register services...
// Get the dependency graph for visualization or debugging
const graph = builder.getDependencyGraph();
console.log(graph);
// {
// 'databaseService': [],
// 'userRepository': ['databaseService'],
// 'userService': ['userRepository']
// }Handling Circular Dependencies
The library automatically detects circular dependencies and throws a descriptive error:
// This would throw: "Circular dependency detected: serviceX -> serviceY -> serviceZ -> serviceX"
builder.register(ServiceX);
builder.register(ServiceY);
builder.register(ServiceZ);
builder.build();License
MIT
Datenwissenschaften und KI Developed with ❤️ by Data Alchemy Team
