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

jurca-di

v0.2.0

Published

A dependency injector for ECMAScript with support for interfaces, type-based dependency configuration and default dependencies.

Downloads

2

Readme

jurca-di

Build Status npm License

A dependency injector for ECMAScript with support for interfaces, type-based dependency configuration and default dependencies.

Quickstart

To install jurca-di dependency injector into your project, simply use npm:

npm install jurca-di

The main class, DependencyInjector is located in the es2015/DependencyInjector.js file. The project is written in ES2015 (ES6), so, if you need to use it in an environment that does not support ES2015, you will need a transpiler, for example babel or traceur. You may also need a JS module library/polyfill if you intend to use this library in a browser, for example SystemJS.

Usage

The Dependency Injector is used for:

  • managing class dependency configuration
  • configuring the preferred implementations of interfaces (unimplemented classes in case of E2015)
  • a registry of shared class instances - this is useful for classes that are used as services.

Note that this dependency injector implementation supports only dependencies that are passed in through the class constructor.

To use this dependency injector, an instance must be first created:

import DependencyInjector from "jurca-di/es2015/DependencyInjector"

let di = new DependencyInjector()

Every instance has its own configuration and instance registry, nothing is shared.

Dependency configuration

Class constructor dependencies are configured using the configure() method:

di.configure(MyClass, firstConstructorDependency, secondConstructorDependency)

You may provide any number of dependencies, they will be passed into the constructor in the same order.

The provided dependencies will be passed in as provided, except for class references (constructor functions) - the dependency injector will use their shared instances in their place.

Note that the dependency injector does not check for cyclic dependencies, so if you happen to create one in your configuration, it will result in an infinite loop.

The order in which the dependencies are configured is irrelevant.

Default dependencies

Your classes may specify their dependencies (useful especially if you use interfaces to wire everything up). To do that, simply declare a static dependencies property on your class:

class MyClass {
  static get dependencies() {
    return [firstConstructorDependency, secondConstructorDependency]
  }
}

// or

class MyClass { ... }
MyClass.dependencies = [
  firstConstructorDependency,
  secondConstructorDependency
]

If, for any reason, you need to use a different name for the property, you may configure it like this:

di.dependenciesPropertyName = "deps"

class MyClass {
  // now we can use the deps property instead of the dependencies property
  static get deps() {
    return [firstConstructorDependency, secondConstructorDependency]
  }
}

Creating shared and individual instances

You will usually need to create or retrieve the shared instances of configured classes. The dependency injector creates these lazily upon first time the instance is needed, either because it was requested, or as a dependency for another class.

The create or retrieve a shared instance, use the get() method:

let instance = di.get(MyClass)
let sameInstance = di.get(MyClass)
// instance === sameInstance

In case that you need to create a new private instance of a class, use the create() method:

let instance = di.create(MyClass)

The create() method also allows you to pass in custom dependencies into the class constructor:

let instance = di.create(MyClass, foo, bar, baz)

Usage with interfaces

The dependency injector allows you to use interfaces (empty classes) as dependencies and specifying the implementation of them to use instead to simplify wiring things up. This is especially useful in combination with default class dependencies and allows you to globally swap an implementing class in the application by editing a single configuration line.

To configure the class the dependency injector should use as implementation of an interface, use the setImplementation() method:

di.setImplementation(FooInterface, FooImplementation)

let instance = di.get(FooInterface)
// (instance instanceof FooImplementation) === true

It is also possible to specify another interface as an interface implementation. The dependency injector will follow the implementation chain to the class:

di.setImplementation(FooInterface, BarInterface)
di.setImplementation(BarInterface, BarImplementation)

let instance = di.get(FooInterface)
// (instance instanceof BarImplementation) === true

The current state of this project

There are no current plans for additional features (unless a good case for adding them is made), but the project accepts bug fixes if new bugs are discovered.

Contributing

Time is precious, so, if you would like to contribute (bug fixing, test writing or feature addition), follow these steps:

  • fork
  • implement (follow the code style)
  • pull request
  • wait for approval/rejection of the pull request

Filing a bug issue might get me to fix the bug, but filing a feature request will not as I don't have the time to work on this project full-time. Thank you for understanding.