npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

dipperts

v0.3.0

Published

Dependency injection library for typescript.

Downloads

11

Readme

DipperTS - A typescript dependency inversion framework

Apply the dependency inversion principle (DIP) to your code with DipperTS.

Installation

npm i dipperts --save

Basic example

First define two classes that depend on each other. Naturally, the dependency should only be on interfaces.

// Interfaces.ts
export interface IMyStore1 {
    doSomething();
}

export interface IMyStore2 {
    doSomethingElse();
}
// MyStore1.ts
import { IMyStore1, IMyStore2 } from "./Interfaces";

export class MyStore1 implements IMyStore1 {
    constructor(private myStore2: IMyStore2){}

    public doSomething() {
        // ...

        this.myStore2.doSomethingElse();

        // ...
    }
}
// MyStore2.ts
import { IMyStore2 } from "./Interfaces";

export class MyStore2 {
    doSomethingElse() {
        // ...
    }
}

Next, setup your container and inject the dependent components into each other:

// MyContainer.ts
import * as dipper from "dipperTS";
import { IMyStore1, IMyStore2 } from "./Interfaces";
import { MyStore1 } from "./MyStore1";
import { MyStore2 } from "./MyStore2";

// define an interface that reflects which 
// components should be available in it
interface IMyContainer {
    myStore1: IMyStore1;
    myStore2: IMyStore2;
}

// create the container builder to setup your container
let builder = new dipper.ContainerBuilder();

// create the container
// - add your interface
// - setup all components (in this case to singletons)
// - create the container
let container = builder.add<IMyContainer>(c => ({
        myStore1: c.single<IMyStore1>(() => new MyStore1(c.myStore2())),
        myStore2: c.single<IMyStore2>(() => new MyStore2())
    }))
    .create();

// resolve MyStore1
let myStore1 = container.myStore1();

// do something with your store
myStore.doSomething();

Resolution Strategies

Single

The single resolution strategy means that the container will only ever create one instance of this service type.

Example:

let container = builder.add<IMyContainer>(c => ({
        myStore2: c.single<IMyStore2>(() => new MyStore2())
    }))
    .create();

// store2 is same instance as store2_2
let store2 = container.myStore2();
let store2_2 = container.myStore2();

Transient

Transient means that whenever this type is requested a new instance is created.

Example:

let container = builder.add<IMyContainer>(c => ({
        myStore2: c.transient<IMyStore2>(() => new MyStore2())
    }))
    .create();

    
// store2 is a different instance than store2_2
let store2 = container.myStore2();
let store2_2 = container.myStore2();

Scoped

Scoped resolution means that per matching scope key a new instance is created. Whenever a scoped service is requested from the same scope the same instance will be returned.

Example:

let container = builder.add<IMyContainer>(c => ({
        myStore2: c.scoped<IMyStore2>(() => new MyStore2(), "myScope")
    }))
    .create();

let container1 = container.startLifetimeScope("myScope");
let container2 = container.startLifetimeScope("myScope");

// store2 and store2_2 are resolved from the same scope
// therefore they are the same
let store2 = container1.myStore2();
let store2_2 = container1.myStore2();

// store2_3 is resolved from another scope, therefore it is different
let store2_3 = container2.myStore2();

Container Provider

The container provider is a means to implement a global provider for a container scope that should be used in any given context.

When you want to use scoped resolution strategy you usually have to implement when to change the scope. Also the scoped container needs to be used to resolve instances in the new scope.

Using the container provider as a global place for dependency resolution you can implement there when to switch the container scopes.

You could use this to provide a new container scope for each url/route that your application is navigated too. By that you can scope instances of your services to specific urls/routes.

Example: Provide a single container throughout the app.

let container = builder.add<IMyContainer>(c => ({
        myStore2: c.scoped<IMyStore2>(() => new MyStore2(), "myScope")
    }))
    .create();

dipper.provideContainerInstance(container);

// container2 will be the same as container1
let container2 = dipper.getContainerProvider().getContainer<IMyContainer>();

Other Topics

  • Container Combinations
  • Resetting the container

License

MIT License