Nest: [core] Bug ModuleRef doesn't resolve component

Created on 19 Nov 2017  路  5Comments  路  Source: nestjs/nest

Hi,

I figure out a problem with ModuleRef as follow from docs: https://docs.nestjs.com/advanced/circular-dependency

@Component()
@Dependencies(ModuleRef)
export class CatsService {
  constructor(moduleRef) {
    this.moduleRef = moduleRef;
  }

  onModuleInit() {
    this.service = this.moduleRef.get(Service);
  }
}

So I try it as this:

import {All, Controller} from '@nestjs/common';
import {ModuleRef} from '@nestjs/core';
import {OnModuleInit} from '@nestjs/common/interfaces/modules';
import {UserService} from '../users/user.service';

@Controller('/graphql')
export class GraphqlController implements OnModuleInit {

    private service: UserService;

    constructor(private readonly moduleRef: ModuleRef, private readonly userService: UserService) {}

    public onModuleInit() {
        this.service = this.moduleRef.get<UserService>(UserService);
        console.log('Modulre ref:', this.service);
        console.log('Constructor inject:', this.userService);
    }

    @All()
    public index(): void {
        // just for middleware
    }
}

But it doesn't work, the output is output:

/home/cojack/.nvm/versions/node/v8.5.0/bin/node /home/cojack/.nvm/versions/node/v8.5.0/lib/node_modules/npm/bin/npm-cli.js run start --scripts-prepend-node-path=auto

> [email protected] start /home/cojack/Projects/private/i-know-nest
> node node_modules/.bin/ts-node $NODE_DEBUG_OPTION src/index.ts

Debugger listening on ws://127.0.0.1:38937/7642ddc1-9ff2-4588-b6f6-014c2ce6bfcb
For help see https://nodejs.org/en/docs/inspector
Debugger attached.
[Nest] 31672   - 2017-11-19 12:35:27   [NestFactory] Starting Nest application...
[Nest] 31672   - 2017-11-19 12:35:27   [InstanceLoader] AppModule dependencies initialized +7ms
[Nest] 31672   - 2017-11-19 12:35:27   [InstanceLoader] DatabaseModule dependencies initialized +556ms
[Nest] 31672   - 2017-11-19 12:35:27   [InstanceLoader] UsersModule dependencies initialized +3ms
[Nest] 31672   - 2017-11-19 12:35:27   [InstanceLoader] GraphqlModule dependencies initialized +1ms
[Nest] 31672   - 2017-11-19 12:35:27   [RoutesResolver] UsersController {/users}: +9ms
[Nest] 31672   - 2017-11-19 12:35:27   [RoutesResolver] GraphqlController {/graphql}: +1ms
[Nest] 31672   - 2017-11-19 12:35:27   [RouterExplorer] Mapped {/, ALL} route +1ms
Modulre ref: null
Constructor inject: UserService {
  repository: 
   MongoRepository {
     manager: MongoEntityManager { repositories: [Array], connection: [Object] },
     metadata: 
      EntityMetadata {
        childEntityMetadatas: [],
        tableType: 'regular',
        isJunction: false,
        ownColumns: [Array],
        ownRelations: [],
        relations: [],
        eagerRelations: [],
        lazyRelations: [],
        columns: [Array],
        ownerColumns: [],
        inverseColumns: [],
        relationIds: [],
        relationCounts: [],
        indices: [],
        foreignKeys: [],
        embeddeds: [],
        listeners: [],
        generatedColumns: [Array],
        primaryColumns: [Array],
        parentIdColumns: [],
        oneToOneRelations: [],
        ownerOneToOneRelations: [],
        oneToManyRelations: [],
        manyToOneRelations: [],
        manyToManyRelations: [],
        ownerManyToManyRelations: [],
        relationsWithJoinColumns: [],
        lazyRelationsWrapper: [Object],
        parentClosureEntityMetadata: undefined,
        target: [Function: UserEntity],
        engine: undefined,
        database: undefined,
        schema: undefined,
        givenTableName: undefined,
        skipSync: false,
        targetName: 'UserEntity',
        tableNameWithoutPrefix: 'user_entity',
        tableName: 'user_entity',
        name: 'UserEntity',
        tablePath: 'user_entity',
        schemaPath: undefined,
        isClassTableChild: false,
        isSingleTableChild: false,
        isEmbeddable: false,
        isClosureJunction: false,
        isClosure: false,
        isAbstract: false,
        isRegular: true,
        orderBy: undefined,
        inheritanceType: undefined,
        discriminatorValue: 'UserEntity',
        treeParentRelation: undefined,
        treeChildrenRelation: undefined,
        hasMultiplePrimaryKeys: false,
        createDateColumn: undefined,
        updateDateColumn: undefined,
        versionColumn: undefined,
        discriminatorColumn: undefined,
        treeLevelColumn: undefined,
        objectIdColumn: undefined,
        propertiesMap: [Object],
        hasNonNullableRelations: false },
     queryRunner: 
      MongoQueryRunner {
        isReleased: false,
        isTransactionActive: false,
        data: {},
        connection: [Object],
        databaseConnection: [Object] } } }
[Nest] 31672   - 2017-11-19 12:35:27   [NestApplication] Nest application successfully started +3ms
[Nest] 31672   - 2017-11-19 12:35:27   [AppDispatcher] Server listening on localhost:3000
[Nest] 31672   - 2017-11-19 12:35:27   [Index] Everything up

It should work? Any help, tips?

Thanks in advance.

Source code available at: https://github.com/cojack/i-know-nest

Most helpful comment

@kamilmysliwiec It would be any possibility to get services from other modules?

Thanks

All 5 comments

I think I know where's the problem, it's a scope. I can inject components only from the current module.

The module reference has a get() method, which allows to retrieve any component available in the current module.

exactly, @kamilmysliwiec it will be possible to extend this functionality?

@kamilmysliwiec any chance to get info how to go over this limitation

in #189 you wrote

Since we have an access to the ModuleRef, it's possible to do the exact same thing as with the NestContainer

but
lets say we have

@Module({
  components: [DataService]
  exports: [DataService]
})
export class DataModule {}

@Module({
  imports: [DataModule]
  components: [UserService]
})
export class DomainModule {}


@Component()
export class UserService {
  constructor(moduleRef: ModuleRef) {
    const dataService = this.moduleRef.get(DataService)
    // OR like in testing module we do
    const dataService = this.moduleRef.select(DataModule).get(DataService)
}
}

for now from moduleRef.get(), we can only get components provided inside my DomainModule, no chance to get any imported components, it just returns null

this feature would help a lot

thanks for your grate work

@kamilmysliwiec It would be any possibility to get services from other modules?

Thanks

This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

JulianBiermann picture JulianBiermann  路  3Comments

mishelashala picture mishelashala  路  3Comments

anyx picture anyx  路  3Comments

artaommahe picture artaommahe  路  3Comments

cdiaz picture cdiaz  路  3Comments