Nevar pievienot vairāk kā 25 tēmas Tēmai ir jāsākas ar burtu vai ciparu, tā var saturēt domu zīmes ('-') un var būt līdz 35 simboliem gara.
 
Iet uz failu
garrettmills 051088732a
continuous-integration/drone/tag Build is failing Papildu informācija
v0.5.0
pirms 4 gadiem
src Start proper IoC refactor pirms 4 gadiem
test More unit tests and code coverage pirms 4 gadiem
.drone.yml promote docs pirms 4 gadiem
.gitignore More unit tests and code coverage pirms 4 gadiem
README.md Update Readme pirms 4 gadiem
index.js update docs pirms 4 gadiem
package.json v0.5.0 pirms 4 gadiem
yarn.lock More unit tests and code coverage pirms 4 gadiem

README.md

flitter-di

Agnostic, unopinionated dependency-injection for Node

The Flitter framework is a sophisticated, service-based framework for building web applications. In an attempt to keep the functionality provided by this framework modular and reusable, its functionality is broken down into services called Units. These Units are run in a particular order to start your Flitter application.

Flitter-DI is the second-generation inversion-of-control dependency-injector used by Flitter to make this work. It was pulled from the libflitter project in the hope that it can remain independent from the rest of Flitter and can be used in other projects.

Injectable classes specify a static array of service names. Then, these static classes are run through the DependencyInjector#inject() method which injects instances of the requested services. Flitter-DI supports a robust, single-instance, cyclically-dependent service structure.

Quick Start

Install with Yarn

yarn add flitter-di

Create a Service

As a trivial example, we're going to define a hello-world service to greet the server:

const { Service } = require('flitter-di')

class HelloWorldService extends Service {
    hi() {
        console.log('Hello, World!')
    }
}

Create the Container & Dependency Injector

Now, we need to create a service container with our HelloWorldService class. We're going to set the name of that service to hello_world:

const { Container, DependencyInjector } = require('flitter-di')

const container = new Container({
    hello_world: require('./HelloWorld.service')
})

const di = new DependencyInjector(container)

Use!

Now, we can use that shiny new dependency injector to access services from Injectable classes:

const { Injectable } = require('flitter-di')
class SomeUsefulClass extends Injectable {
    static get services() {
        return ['hello_world']
    }
    
    run() {
        this.hello_world.hi()
    }
}

Back in our start code:

const SomeUsefulClass = di.make(require('./SomeUsefulClass'))
const useful = new SomeUsefulClass()

useful.run() // Hello, World!

Alternatively, we can fetch services from the dependency injector directly:

// Fetch the service directly
di.get('hello_world').hi() // Hello, World!

// Or use the service object
const service = di.proxy()
service.hello_world.hi() // Hello, World!

Circular Dependencies

For the curious, yes. Flitter-DI will resolve circular dependencies. It's still not recommended however:

const { Container, DependencyInjector, Service } = require('flitter-di')

class A extends Service {
    static get services() {
        return ['b']
    }
}

class B extends Service {
    static get services() {
        return ['a']
    }
}

const container = new Container({ a: A, b: B })
const di = new DependencyInjector(container)

const service = di.proxy()

service.a // A { }
service.a.b // B { }
service.b.a // A { }

service.a.foo = "Bar" // A { foo: "Bar" }
service.a.b.a.b.a.b.a.foo // "Bar"

Deferred Services

Sometimes, it may be that services don't always load in an order that ensures that all injectable classes are loaded after the services themselves. In these cases, Flitter DI will defer the injection of the missing services until they are registered with the service container. When they are registered, the class will be injected with those services, as well as any instances of the class that were created before the service was registered. A basic example:

const { Service, Injectable, DependencyInjector } = require('flitter-di')

class A extends Service {
    number = 3.141
}

class B extends Service {
    number = (22/7)
}

class MyClass extends Injectable {
    static get services() {
        return ['a', 'b']
    }
}

const di = new DependencyInjector()
di.container.register_service('a', A)

const my_class = di.make(MyClass)

console.log(my_class.a) // => A { number: 3.141 }
console.log(my_class.b) // => B { }

di.container.register('b', B)

console.log(my_class.a) // => A { number: 3.141 }
console.log(my_class.b) // => B { number: 3.142 }

// Note that you can disable deferred injection like so:
class BuzzKill extends Injectable {
    static _di_allow_defer = false
}

Singletons

Because flitter-di provides full IoC, you can register and use singletons with the dependency container like so:

di.container.register_singleton('math_pi', 3.1415)

di.get('math_pi') // => 3.1415

class MathClass extends Injectable {
    static get services() {
        return ['math_pi']
    }
}

const math = di.make(MathClass)
math.math_pi // => 3.1415

License

Copyright 2019 Garrett Mills

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

Testing

flitter-di has both unit and integration tests in-repo. You can run these like so:

yarn run test_units
yarn run test_integration