Comparisons
Compare udic with other DI libraries.
Basic injection
Section titled “Basic injection”Use and inject one dependency.
- Bundle size: 473B
- Minified size: 215B
- Gzipped size: 177B
import * as di from 'udic';
const random = di.service('random')<() => number>();const main = di.use([random], (random) => { console.log('Random number:', random());});
main({ random: Math.random });
- Bundle size: 78.64KB
- Minified size: 21.49KB
- Gzipped size: 7.41KB
import { Micro, Context } from 'effect';
class Random extends Context.Tag('Random')<Random, Micro.Micro<number>>() {}
const program = Micro.gen(function* () { const random = yield* Micro.service(Random); console.log('Random number:', yield* random);});
Micro.runSync(Micro.provideService(program, Random, Micro.sync(Math.random)));
Multiple dependencies
Section titled “Multiple dependencies”Use and inject dependencies in different function layers.
- Bundle size: 1.1KB
- Minified size: 534B
- Gzipped size: 351B
import * as di from 'udic';
const logger = di.service('logger')<{ info: (msg: string) => void;}>();const createId = di.service('createId')<() => string>();
interface User { readonly name: string; readonly id: string; readonly credits: number;}
// Functions that requires dependencies to runconst createUser = di.use( [createId, logger], (createId, logger) => (name: string): User => { const id = createId(); logger.info(`User created: id="${id}", name="${name}"`); return { name, id, credits: 0 }; },);
const giveUserCredits = di.use( [logger], (logger) => (user: User, credits: number) => { // @ts-ignore user.credits += credits; logger.info( `User credits: id="${user.id}", increased-credits=${credits}, current-credits=${user.credits}`, ); },);
// Main programconst main = di.use( [createUser, giveUserCredits], (createUser, giveUserCredits) => { const user = createUser('reve'); giveUserCredits(user, 10); },);
main({ logger: { info: (msg) => console.info('[INFO]', msg), }, createId: () => '' + Math.round(Math.random() * 1e6),});
- Bundle size: 79.32KB
- Minified size: 21.89KB
- Gzipped size: 7.58KB
import { Micro, Context } from 'effect';
class Logger extends Context.Tag('Logger')< Logger, { info: (msg: string) => Micro.Micro<void>; }>() {}class CreateID extends Context.Tag('CreateID')< CreateID, Micro.Micro<string>>() {}
interface User { readonly name: string; readonly id: string; readonly credits: number;}
// Functions that requires dependencies to runconst createUser = (name: string) => Micro.gen(function* () { const logger = yield* Micro.service(Logger); const createId = yield* Micro.service(CreateID);
const id = yield* createId; yield* logger.info(`User created: id="${id}", name="${name}"`);
return { name, id, credits: 0 } as User; });
const giveUserCredits = (user: User, credits: number) => Micro.gen(function* () { const logger = yield* Micro.service(Logger);
// @ts-ignore user.credits += credits; yield* logger.info( `User credits: id="${user.id}", increased-credits=${credits}, current-credits=${user.credits}`, ); });
// Main programconst main = Micro.gen(function* () { const user = yield* createUser('reve'); yield* giveUserCredits(user, 10);});
Micro.runSync( main.pipe( Micro.provideService(Logger, { info: (msg) => Micro.sync(() => { console.info('[INFO]', msg); }), }), Micro.provideService( CreateID, Micro.sync(() => '' + Math.round(Math.random() * 1e6)), ), ),);
Dependent services
Section titled “Dependent services”Use and inject 3 dependencies, with log
depends on config
and db
depends on both log
and config
.
- Bundle size: 1.15KB
- Minified size: 606B
- Gzipped size: 414B
import * as di from 'udic';
// Declarationsconst config = di.service('config')<{ logLevel: string; connection: string;}>();const log = di.service('log')<(msg: string) => void>();const db = di.service('db')<{ query: (sql: string) => { result: string };}>();
const main = di.use([db, log], (db, log) => { log(db.query('SELECT * FROM users').result);});
// Implementationsconst logImpl = di.impl( log, di.use([config], (config) => (msg) => { console.log(`[${config.logLevel}] ${msg}`); }),);const dbImpl = di.impl( db, di.use([config, log], (config, log) => ({ query(sql) { log('Executing query: ' + sql); return { result: 'Results from ' + config.connection }; }, })),);
// Link dependenciesconst logDeps = di.link([logImpl], { config: { logLevel: 'INFO', connection: 'mysql://username:password@hostname:port/database_name', },});const dbDeps = di.link([dbImpl], logDeps);
// Run with linked dependenciesmain(dbDeps);
- Bundle size: 1MB
- Minified size: 210.77KB
- Gzipped size: 67.78KB
import { Effect, Context, Layer } from 'effect';
class Config extends Context.Tag('Config')< Config, { logLevel: string; connection: string; }>() {}
class Logger extends Context.Tag('Logger')< Logger, (message: string) => Effect.Effect<void>>() {}
class Database extends Context.Tag('Database')< Database, { query: (sql: string) => Effect.Effect<{ result: string }> }>() {}
const program = Effect.gen(function* () { const database = yield* Database; const log = yield* Logger;
const data = yield* database.query('SELECT * FROM users'); yield* log(data.result);});
const ConfigLive = Layer.succeed(Config, { logLevel: 'INFO', connection: 'mysql://username:password@hostname:port/database_name',});
const LoggerLive = Layer.effect( Logger, Effect.gen(function* () { const config = yield* Config;
return (message) => Effect.sync(() => { console.log(`[${config.logLevel}] ${message}`); }); }),);
const DatabaseLive = Layer.effect( Database, Effect.gen(function* () { const config = yield* Config; const log = yield* Logger;
return { query: (sql) => Effect.gen(function* () { yield* log('Executing query: ' + sql); return { result: 'Results from ' + config.connection }; }), }; }),);
Effect.runSync( program.pipe( Effect.provide(DatabaseLive), Effect.provide(LoggerLive), Effect.provide(ConfigLive), ),);