thiagobustamante / typescript-ioc

A Lightweight annotation-based dependency injection container for typescript.
MIT License
526 stars 64 forks source link

@Provides in different file #11

Closed kozubikmichal closed 6 years ago

kozubikmichal commented 7 years ago

Hi,

I have issue using your IoC when the abstract class and providing class are in different files.

This is working just fine:

import { Inject, Provides } from "typescript-ioc"

abstract class IFoo {
    abstract bar()
}

@Provides(IFoo)
class Foo implements IFoo {
    bar() {
        console.log("Foo bar");
    }
}

class Worker {
    @Inject
    private foo: IFoo

    work() {
        this.foo.bar()
    }
}

new Worker().work()

However when I split it into the 3 files I get the "TypeError: this.foo.bar is not a function" error:

index.ts:

import { Inject } from "typescript-ioc"
import IFoo from "./IFoo";
import Foo from "./Foo";

class Worker {
    @Inject
    private foo: IFoo

    work() {
        this.foo.bar()
    }
}

new Worker().work()

IFoo.ts:

export default abstract class IFoo {
    abstract bar()
}

Foo.ts:

import { Provides } from "typescript-ioc"
import IFoo from "./IFoo"

@Provides(IFoo)
export default class Foo implements IFoo {
    bar() {
        console.log("Foo bar");
    }
}
thiagobustamante commented 7 years ago

Hi,

Thank for reporting. I'm out of home this week, on vacation with the kids. But I'll be back on the 25th and I promise to look at it as soon as I get home.

thiagobustamante commented 7 years ago

I added a test case that reproduces the problem. I will take a look at it now

kozubikmichal commented 7 years ago

Any progress?

thiagobustamante commented 6 years ago

The problem is that typescript-ioc does not scan any folder looking for classes. Your classes must be previously imported.

require('./Foo'); // or import { Foo } from "./Foo";

new Worker().work()

The above code would make it work.

So, I created another helper method that can help to include sources in the container context for those code that are not already referenced. (You only need to include things that are not already imported).

import { ContainerConfig } from "typescript-ioc/container-config";

ContainerConfig.addSource('lib/*'); // You can use glob patterns here
// or
ContainerConfig.addSource('controllers/*', 'baseFolder');
// or 
ContainerConfig.addSource(['**/*', '!foo.js'], 'baseFolder');

You need to configure those sources only once, but before you try to use the objects that depends on these files

kozubikmichal commented 6 years ago

Unfortunately I'm not able to get this work. I created a new project with the most actual version of typescript-ioc package and when I try to import ContainerConfig as described above, I'm getting ts error Cannot find module 'typescript-ioc/container-config'. I looked at the node_modules folder and the file is present but for some reason typescript cannot find it

image

thiagobustamante commented 6 years ago

Sorry, I found an error in publishing the package. Please try again with version 1.0.2

kozubikmichal commented 6 years ago

Still no success. My folder structure:

image

Foo.ts:

import { Provides } from "typescript-ioc"

import IFoo from "./IFoo";

@Provides(IFoo)
export default class Foo extends IFoo {
    bar() {
        console.log("bar called");
    }
}

IFoo.ts:

export default abstract class IFoo {
    abstract bar();
}

index.ts:

import { Inject, Container, Config } from "typescript-ioc";

import { ContainerConfig } from "typescript-ioc/container-config";

import IFoo from "./IFoo";

ContainerConfig.addSource(["**/*", "!index.ts"], 'src');

class Worker {
    @Inject
    private foo: IFoo;

    work() {
        this.foo.bar();
    }
}

new Worker().work();

tsconfig.json:

{
  "compilerOptions": {
    "outDir": "./dist/",
    "sourceMap": true,
    "noImplicitAny": false,
    "module": "commonjs",
    "target": "es3",
    "experimentalDecorators": true,
    "emitDecoratorMetadata": true,
    "lib": [
      "dom", "es6"
    ]
  },
  "include": [
    "./src/**/*"
  ]
}

when I run tsc && node dist/index.js I'm getting this error:

image

thiagobustamante commented 6 years ago

I did not test this library with "target": "es3". Can you make a test compiling it to ES5?

kozubikmichal commented 6 years ago

still the same issue with both ES5 and ES6