Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

@Inject() doesn't work, Container.get() does #93

Closed
lsmialowski opened this issue Apr 12, 2019 · 9 comments
Closed

@Inject() doesn't work, Container.get() does #93

lsmialowski opened this issue Apr 12, 2019 · 9 comments

Comments

@lsmialowski
Copy link

lsmialowski commented Apr 12, 2019

Hi, I'm facing weird issue,
Container.get(MyServiceName); returns demanded service, yet class property decorated with @Inject() is undefined.

My tsconfig.json:

{
"compilerOptions": {

    "declaration": true,
    "pretty": true,
    "esModuleInterop": true,
    "target": "esnext",
    "noImplicitAny": true,
    "noImplicitReturns": true,
    "noUnusedLocals": false,
    "moduleResolution": "node",
    "noUnusedParameters": true,
    "strictPropertyInitialization": false,
    "module": "commonjs",
    "lib": ["dom", "es2018"],
    "importHelpers": true,
    "outDir": "./dist",
    "strict": true,
    "typeRoots": ["node_modules/@types"],
    "experimentalDecorators": true,
    "emitDecoratorMetadata": true,
    "sourceMap": true
  },
  "include": ["./src/**/*"],
  "exclude": ["node_modules", "./dist/**/*"]
}

Service that I want to be injected

import MyServiceName from '../services/MyServiceName';
import { Container, Inject, Service } from 'my_dependency/lib';

export default class SomeClass{
  @Inject()
  private readonly someService: MyServiceName;

  public async someMethod(): SomeResponseType {
    const thatWorks = Container.get<MyServiceName>(MyServiceName);
    console.log(this.someService); // undefined
    console.log(thatWorks); // proper class
  }
}

Service I want to inject

@Service()
export default class MyServiceName {
  public async someMethod(): SomeReturnType {
    return someReturnedData;
  }
}

I do import reflect-metada at entry point of my application

import 'reflect-metadata';

I'm wondering if it may be related to fact, that that I'm using typedi not directly from my node_modules but from my dependency?

Application doesn't use Express framework neither routing controllers

@georgyfarniev
Copy link

georgyfarniev commented May 1, 2019

I have same issue, example below doesn't work, but works if I call Container.get instead:

import 'reflect-metadata'
import assert from 'assert'
import {Container, Service, Inject} from 'typedi'

const key = 'authorization-token'
const data = 'RVT9rVjSVN'

Container.set(key, data)

@Service()
class UserRepository {
  @Inject(key)
  public authorizationToken: string;
}

const tmp = new UserRepository()

assert(tmp.authorizationToken === undefined)
assert(Container.get(key) === data)

console.log('asserts passed')

Result:

$ node dist/test.js
asserts passed

My tsconfig have:

"emitDecoratorMetadata": true,
"experimentalDecorators": true,

Typedi version: 0.8.0
Node: 11
Typescript: 3.2.2

@pleerock
Copy link
Contributor

pleerock commented May 3, 2019

@georgyfarniev are you claiming about bug, but its actually wrong use from your side. Same happen for 80-90% issues usually opened on a github for open source projects. They are just questions or improper usage. In your case you shouldn't use new UserRepository(), you must use Container.get(UserRepository) to get service instance with properly injected dependencies.

@pleerock
Copy link
Contributor

pleerock commented May 3, 2019

Same maybe true for @lsmialowski request. He didn't actually decorated his SomeClass class with a @Service decorator and didn't show how he is calling that service.

@georgyfarniev
Copy link

@pleerock thank you for response. I will fix it in my code

@nachocodexx
Copy link

@pleerock if I didn't forget the @service decorator and when I'm try to inject some value using @Inject does not work , It gives undefined.

@NoMan2000
Copy link

NoMan2000 commented Apr 23, 2020

I have the same problem. I have all the services marked as @Service.

Whenever I tried in both the constructor initialization version and the property declaration version to use @Inject, I always got undefined.

Then I tried using Container.set to alias the classes to a string and then using that in the @Inject('aliasname').

None of that worked. But using Container.get(class) did work as the default parameter in the constructor or as the property value.

So I have to agree that there's something up with the @Inject decorator, it does not seem to work the way that the docs say it does.

@devmattrick
Copy link

I'm also having issues with this. It seems to not work only in some cases but I haven't quite been able to track down exactly why it's happening.

@justinmchase
Copy link

There is a high probability that you have a circular reference such that:

import MyService from "./MyService";
console.log(MyService) // undefined

@Service()
export class MyController {

  // Injection fails because metadata is added to the class as the module is loaded
  // At the time the module loads in a circular dependency scenario the type was undefined
  // Later because of the way the import is an object and the exported members are references
  // on that module, the Type will appear. The it will always be undefined in the Reflect metadata.
  @Inject()
  private service: MyService 

  constructor() {
    console.log(this.service) // undefined
    console.log(MyService) // MyService is now defined after both modules are done loading
    console.log(Container.get(MyService)) // MyService instance is created
  }
}

@NoNameProvided
Copy link
Member

The core takeaway here:

  • you need to decorate your classes you want to Inject
  • you need to initialize your class where your service is injected via Container.getInstance so TypeDI can resolve the dependencies for you.

This issue has multiple unrelated discussions now. Closing and lockin discussion. If anyone still experiences any difficulties, open a new issue. Thanks.

@typestack typestack locked as resolved and limited conversation to collaborators Jul 30, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Development

No branches or pull requests

8 participants