Kernel API
The Kernel is Vla’s dependency injection container. It manages class instantiation, dependency resolution, and instance caching.
Constructor
Section titled “Constructor”new Kernel()Creates a new Kernel instance.
Example:
import { Kernel } from 'vla'
const kernel = new Kernel()Methods
Section titled “Methods”scoped()
Section titled “scoped()”scoped(): KernelCreates a new scoped kernel that inherits from the parent kernel. Scoped kernels have their own invoke cache but share the parent’s singleton cache.
Returns: A new scoped Kernel instance
Example:
const rootKernel = new Kernel()const scopedKernel = rootKernel.scoped()
// Each request should get its own scoped kernelapp.use((req, res, next) => { const requestKernel = rootKernel.scoped() // Use requestKernel for this request})Use cases:
- Creating request-scoped kernels in web servers
- Isolating test instances
- Creating temporary dependency overrides
bind()
Section titled “bind()”bind<TKey extends Token>( key: TKey, impl: InstantiableClass<unknown>, scope?: Scope): voidBinds a class implementation to a token (usually another class).
Parameters:
key- The token to bind (typically a class)impl- The implementation class to usescope- Optional scope override ('singleton','invoke', or'transient'). Defaults to'transient'
Example:
// Replace UserRepo with MockUserRepokernel.bind(UserRepo, MockUserRepo)
// Bind with specific scopekernel.bind(UserRepo, MockUserRepo, 'singleton')Use cases:
- Mocking dependencies in tests
- Swapping implementations (e.g., dev vs production)
- Providing alternative implementations
bindValue()
Section titled “bindValue()”bindValue<TKey extends Token>( key: TKey, value: Resolved<TKey>, scope?: Scope): voidBinds a specific value to a token.
Parameters:
key- The token to bindvalue- The value to injectscope- Optional scope ('singleton','invoke', or'transient'). Defaults to'singleton'
Example:
// Bind a mock objectkernel.bindValue(UserRepo, { findById: async (id) => ({ id, name: 'Test User' })})
// Bind configurationkernel.bindValue(Config, { apiKey: 'test-key', databaseUrl: 'postgres://localhost'})Use cases:
- Providing mock objects in tests
- Injecting configuration values
- Providing primitive values or POJOs
context()
Section titled “context()”context<TKey extends Token>( key: TKey, value: Resolved<TKey>): KernelA convenience method for binding a value with invoke scope. Returns the kernel for chaining.
Parameters:
key- The context tokenvalue- The context value
Returns: The kernel instance (for chaining)
Example:
const AppContext = Vla.createContext<{ userId: string cookies: Record<string, string>}>()
const scoped = kernel .scoped() .context(AppContext, { userId: '123', cookies: req.cookies })Use cases:
- Providing request-scoped context
- Chaining multiple context providers
- Setting up test context
resolve()
Section titled “resolve()”resolve<T>(key: Token<T>, scope?: Scope): TResolves a dependency and returns an instance. Does not perform unwrapping.
Parameters:
key- The token to resolvescope- Optional scope override
Returns: An instance of the requested type
Example:
const service = kernel.resolve(UserService)const customScope = kernel.resolve(UserService, 'singleton')Note: Most users should use create() or get() instead. Use resolve() when you specifically need to bypass unwrapping.
get<T>(key: Token<T>, scope?: Scope): TResolves a dependency and performs unwrapping if the class has an unwrap property.
Parameters:
key- The token to resolvescope- Optional scope override
Returns: An instance of the requested type (unwrapped if applicable)
Example:
class Database extends Vla.Resource { static readonly unwrap = 'client' client = new PrismaClient()}
// Without unwrapconst dbInstance = kernel.resolve(Database) // Database instanceconst client = dbInstance.client // PrismaClient
// With unwrapconst client = kernel.get(Database) // PrismaClient directlycreate()
Section titled “create()”create<T>(cls: InstantiableClass<T>): TCreates a new instance of a class and injects its dependencies.
Parameters:
cls- The class to instantiate
Returns: A new instance with dependencies injected
Example:
const service = kernel.create(UserService)const action = kernel.create(GetUserAction)