Giter Site home page Giter Site logo

simpleinjection's Introduction

SimpleInjection

A very simple dependency injection library in TypeScript leveraging decorators and with support for using from pure Javascript. Features:

  • No external dependencies
  • TypeScript decorators
  • Instance lifetime: Transient and Container
  • Strongly typed factories for specifing additional constructor parameters
  • Doesn't require TypeScript metadata information
  • Usable from pure Javascript (without decorators)

Decorator usage

Decorate classes with @injectable or @injectableAs to specify an interface/symbol the class is provinding (multiple decorators per class allowed). You can specify instance lifetime in the decorator.

Decorate constructor parameters with @inject and specify class/interface/symbol to inject. This is a bit of redundancy that can be eliminated using metadata information, but I didn't want to require metadata for now.

@injectable
class Test {
    constructor() {}
}

@injectable
class TestInject {
    constructor(@inject(Test) private t: Test) {}
}

Javascript usage

Register classes with Container.register or Container.registerInterface to specify an interface/symbol the class is providing.

Specify dependencies as a simple array corresponding to constructor parameters.

container.register(Test, Lifetime.Transient);
container.register(TestInject, Lifetime.Transient, [Test]);

Resolving

Use the Contrainer.resolve method to resolve a class/interface/symbol.

container.resolve(TestInject);

Use the Container.factory method to get a factory producing instance of the resolved class. This can be made strongly typed using an interface extending IFactory<T>.

@injectable
class ParamTest {
    constructor(@inject(Test) private t: Test, additionalParam: string) {}
}

interface ParamFactory extends IFactory<ParamTest> {
    create(prefix: string): ParamTest;
}

const f = container.factory<ParamFactory>(ParamTest);
f.create("some additional param");

Caveats

  • If you use decorators or just class/constructor names to register things a simple toString() is called instead of trying to just get the classname.
  • Typescript doesn't allow to use interface names, so I recommend to declare a simple string value along with the interface with the same name and use this to register interfaces.

To do

  • Proper TS module
  • Some name changes and get rid of DI namespace
  • Validating factory parameter correctness (e.g. number of parameters)
  • Metadata support (for validating factory parameters and automatically injecting constructor parameters)
  • Waiting for ideas...

simpleinjection's People

Contributors

adinfimum avatar

Stargazers

 avatar  avatar

Watchers

 avatar  avatar  avatar

simpleinjection's Issues

Suggestions: LifetimeManager and Child Container or Registration Sources

Good job, mate.

How about extending the "Lifetime" into the Unity way:

export interface LifetimeManager { created(container: Container, item: any): any }
using inside Container and implementing this interface outside of Container would allow you to support current behaviors: Instance, Container(which is not currently trully supported) and open up for others.
I could easily imagine how ProxyLifetimeManager, DisposableLifetimeManager, could work with this.

Adding some more data about RegisteredType and different steps into interface would let you implement, some other - more exotic - ones such as HierarchyControlledLifetimeManager, ObjectPoolingLifetimeManager.

My other thoughts are about the child() method. Currently, it is essentially coping registrations(copy()?) into new Container. How I am imagining this, the ChildContainer should contain a reference to parent and resolve registrations that it does not have, through the parent Container. Also - reverting the orientation - resolving through parent could allow for resolving through known children, prioritising the Parents registrations. Both of these cases (parent using children for resolve and children using parent) could be somewhat confusing about expected behavior(ContainerLifetime for instance), therefore I would suggest using some alternative naming and interfaces, such as RegistrationSources and go through them - in order - during resolving.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.