microsoft / tsyringe

Lightweight dependency injection container for JavaScript/TypeScript
MIT License
5.19k stars 172 forks source link

Providers are being resolved when not registered through any mechanism #162

Closed rhyek closed 3 years ago

rhyek commented 3 years ago

Describe the bug Providers are being resolved when not registered through any mechanism.

To Reproduce

import 'reflect-metadata';
import { container } from 'tsyringe';

class UserService {
  get() {
    return { username: 'root' };
  }
}

const instance = container.resolve(UserService);

console.log('registered?', container.isRegistered(UserService));
console.log('instance found?', !!instance);
console.log('user:', instance?.get());

Expected behavior should output:

registered? false
instance found? false
user: undefined

actual output:

registered? false
instance found? true
user: { username: 'root' }

Version: 4.5.0

rhyek commented 3 years ago

Actually I was expecting some sort of error thrown which I think should be the correct behaviour.

rhyek commented 3 years ago

I understand now that resolve here is similar to inversify's resolve, but there is no get in tsyringe that provides a sort of "strict" alternative.

MeltingMosaic commented 3 years ago

Yeah, this is the by-design behavior - given a constructor, TSyringe will attempt to resolve it when requested, even if it's not registered. This is behavior brought over from the old C# Unity container.

mkq commented 1 month ago

This is really dangerous for our use case. As described in #245, we use child containers for properly configured instances of OpenAPI-generated classes. If we accidentally resolve such a class from the root container, we will get an unwanted default instance which calls the base URL that the OpenAPI generator copied from the YAML spec into the code.

Guess I'll have to keep the GitHub workflow check that all servers in the YAMLs must be ….example.org. That check was meant to be removed once we have our DI / configuration set up.