Skip to content

@provide support #190

Description

@remojansen

Expected Behavior

Developers want a new decorator @provide which generates bindings for us. The @provide decorator needs access to a kernel instance;

let kernel = new Kernel();
let provide = makeProvideDecorator(kernel);

The @provide decorator will have a very similar behavior to the kernel.bind fluent API:

// AKA kernel.bind<any>(MyService1).to(MyService1).inSingletonScope()
@provide().inSingletonScope().done()
class MyService1 {}

// AKA kernel.bind<any>(MyService2).to(MyService2).inTransientScope()
@provide().inTransientScope().done()
class MyService2 {}

// AKA kernel.bind<any>(Katana).to(Katana).whenTargetTagged("canThrow", false)
@provide().whenTargetTagged("canThrow", false).done()
class Katana {}

// AKA kernel.bind<any>(Shuriken).to(Shuriken).whenTargetTagged("canThrow", true)
@provide().whenTargetTagged("canThrow", true).done()
class Shuriken {}

When the @provide decorator is used the @injectable decorator will not be mandatory.

We will also provide documented recipes for developers to explain how to create aliases:

let provideSingleton = provide().inSingletonScope().done();
let provideTransient = provide().inTransientScope().done();
let provideThrowable = provide().whenTargetTagged("canThrow", true).done();

This will make the API less verbose:

@provideSingleton
class Katana {}

@provideTransient
class Katana {}

@provideThrowable
class Shuriken {}

Current Behavior

Declaration of bindings via @provide is not currently supported.

Possible Solution

We can wrap the kernel.bind fluent syntax so it includes the done method. The done method must return a class decorator. The class decorator will invoke the kernel.bind method.

Context

This feature was proposed by @otbe on #187.

This might be developed as an optional plugin:

import makeProvideDecorator from "inversify-utils";
import { Kernel } from "inversify";

let kernel = new Kernel();
let provide = makeProvideDecorator(kernel);

let provideSingleton = provide().inSingletonScope().done();
let provideTransient = provide().inTransientScope().done();
let provideThrowable = provide().whenTargetTagged("canThrow", true).done();

export { provide, provideSingleton, provideTransient, provideThrowable };
import { 
    provide, 
    provideSingleton, 
    provideTransient, 
    provideThrowable 
} from "./ioc/decorators";

@provideSingleton
class Katana {}

@provideTransient
class Katana {}

@provideThrowable
class Shuriken {}

@provide().whenTargetTagged("canThrow", true).done();
class Katana {}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions