0.0.15 • Published 1 year ago

hook-di v0.0.15

Weekly downloads
-
License
MIT
Repository
github
Last release
1 year ago

hook-di

Reconsidering dependencies injection in hook style programming.

Highly inspired by vue composition apis.

usage

here is the interfaces

export interface IServiceA {
  a: string;
  hello(): string;
}

export interface IServiceB {
  b: string;
  hello(): string;
}

to turn typescript interfaces to a real JS object, use type InjectionKey and Symbol.

import type { InjectionKey } from "hook-di"; // equal to { InjectionKey } from 'vue'
export const IServiceA: InjectionKey<IServiceA> = Symbol("store a");
export const IServiceB: InjectionKey<IServiceB> = Symbol("store b");

define implements to interfaces

function createServiceB(): IServiceB {
  return {
    b: "storeb",
    hello() {
      return "storeb";
    },
  };
}

function createServiceA(): IServiceA {
  const storeB = inject(IServiceB);
  return {
    a: "storea",
    hello() {
      return storeB.hello() + "storea";
    },
  };
}

manually provide dependencies and auto inject.

import { inject, provide, createDIScope, getCurrentScope } from "../src";

function provides() {  
    provide(IServiceA, createServiceA);
    provide(IServiceB, createServiceB);
}
// use scope to create isolated contexts
const scope = createDIScope();
scope.run(provides);
scope.run(() => {
  const serviceA = inject(IServiceA);
  serviceA.hello(); // "storebstorea"

  // if want to pass the scope, use getCurrentScope
  const currentScope = getCurrentScope()!;
  setTimeout(() => {
    currentScope.run(() => {
      const serviceB = inject(IServiceB);
      serviceB.hello(); // "storeb"
    });
  }, 1000);
})

specify dependencies

provide(IServiceA, createServiceA);
provide(IServiceB, createServiceB);

const provision = provide(IServiceC, createServiceC);

// injection in createServiceC will be createServiceB2
provision.specify(IServiceB, createServiceB2);

// injection in createServiceC will be createServiceA2
const subProvision = provision.specify(IServiceA, createServiceA2);

// injection in createServiceC in createServiceA2 will be createServiceB2
// but ServiceB2 in createServiceC is not shared with ServiceB2 in createServiceA2
subProvision.specify(IServiceB, createServiceB2);

use in vue

import { createDIScope, useInject, useProvide } from "hook-di/vue";

const app = createApp({
    setup() {
        const serviceA = useInject(IServiceA);
        const serviceB = useInject(IServiceB);
    }
});
// isolated context created in here
app.use(createDIScope(), () => {
    useProvide(IServiceA, createServiceA);
    useProvide(IServiceB, createServiceB);
});
app.mount("#app");
0.0.14

2 years ago

0.0.15

1 year ago

0.0.11

2 years ago

0.0.12

2 years ago

0.0.13

2 years ago

0.0.10

2 years ago

0.0.9

2 years ago

0.0.8

2 years ago

0.0.7

2 years ago

0.0.6

2 years ago

0.0.5

2 years ago

0.0.4

2 years ago

0.0.3

2 years ago

0.0.2

2 years ago

0.0.1

2 years ago