{"id":13580819,"url":"https://github.com/thiagobustamante/typescript-ioc","last_synced_at":"2025-05-15T16:04:10.191Z","repository":{"id":8256900,"uuid":"57401488","full_name":"thiagobustamante/typescript-ioc","owner":"thiagobustamante","description":"A Lightweight annotation-based dependency injection container for typescript.","archived":false,"fork":false,"pushed_at":"2024-07-11T21:56:20.000Z","size":873,"stargazers_count":528,"open_issues_count":35,"forks_count":64,"subscribers_count":12,"default_branch":"master","last_synced_at":"2025-05-05T14:47:43.426Z","etag":null,"topics":["cdi","decorators","dependency-injection","es7-decorators","ioc","ioc-container","typescript"],"latest_commit_sha":null,"homepage":null,"language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/thiagobustamante.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2016-04-29T17:25:28.000Z","updated_at":"2025-04-22T11:24:20.000Z","dependencies_parsed_at":"2024-10-22T22:52:28.325Z","dependency_job_id":null,"html_url":"https://github.com/thiagobustamante/typescript-ioc","commit_stats":{"total_commits":154,"total_committers":14,"mean_commits":11.0,"dds":0.6038961038961039,"last_synced_commit":"e0287c917b5561651242239d0c9caea1b91db558"},"previous_names":[],"tags_count":38,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thiagobustamante%2Ftypescript-ioc","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thiagobustamante%2Ftypescript-ioc/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thiagobustamante%2Ftypescript-ioc/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thiagobustamante%2Ftypescript-ioc/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/thiagobustamante","download_url":"https://codeload.github.com/thiagobustamante/typescript-ioc/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254374403,"owners_count":22060609,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cdi","decorators","dependency-injection","es7-decorators","ioc","ioc-container","typescript"],"created_at":"2024-08-01T15:01:55.335Z","updated_at":"2025-05-15T16:04:10.168Z","avatar_url":"https://github.com/thiagobustamante.png","language":"TypeScript","funding_links":[],"categories":["TypeScript"],"sub_categories":[],"readme":"[![npm version](https://badge.fury.io/js/typescript-ioc.svg)](https://badge.fury.io/js/typescript-ioc)\n[![Build Status](https://travis-ci.org/thiagobustamante/typescript-ioc.png?branch=master)](https://travis-ci.org/thiagobustamante/typescript-ioc)\n[![Coverage Status](https://codecov.io/gh/thiagobustamante/typescript-ioc/branch/master/graph/badge.svg)](https://codecov.io/gh/thiagobustamante/typescript-ioc)\n[![Known Vulnerabilities](https://snyk.io/test/github/thiagobustamante/typescript-ioc/badge.svg?targetFile=package.json)](https://snyk.io/test/github/thiagobustamante/typescript-ioc?targetFile=package.json)\n\n# IoC Container for Typescript - 3.X\nThis is a lightweight annotation-based dependency injection container for typescript.\n\nIt can be used on browser, on react native or on node.js server code.\n\n**The documentation for the previous version can be found [here](https://github.com/thiagobustamante/typescript-ioc/wiki/Typescript-IoC-1.x)**\n\n\n**Table of Contents** \n\n- [IoC Container for Typescript](#)\n  - [Installation](#installation)\n  - [Configuration](#configuration)\n  - [Basic Usage](#basic-usage)\n  - [Scopes](#scopes)\n    - [Singleton Scope](#singleton)\n    - [Request Scope](#inrequestscope)\n    - [Local Scope](#local-scope)\n    - [Custom Scopes](#custom-scopes)\n  - [@Factory](#factories)\n  - [@OnlyInstantiableByContainer](#the-onlyinstantiablebycontainer-annotation)\n  - [The Container Class](#the-container-class)\n    - [@InjectValue decorator and Constants](#injectvalue-decorator-and-constants)\n    - [Namespaces (Environments)](#namespaces-environments)\n    - [Creating temporary configurations](#creating-temporary-configurations)\n    - [Importing configurations from external file](#importing-configurations-from-external-file)\n  - [A note about classes and interfaces](#a-note-about-classes-and-interfaces)\n  - [Examples](#examples)\n    - [Using Container for testing](#using-container-for-testing)\n    - [Using Namespaces](#using-namespaces)\n  - [Browser usage](#browser-usage)\n  - [Restrictions](#restrictions)\n  - [Migrating from previous version](#migrating-from-previous-version)\n## Installation\n\nThis library only works with typescript. Ensure it is installed:\n\n```bash\nnpm install typescript -g\n```\n\nTo install typescript-ioc:\n\n```bash\nnpm install typescript-ioc\n```\n\n## Configuration\n\nTypescript-ioc requires the following TypeScript compilation options in your tsconfig.json file:\n\n```typescript\n{\n  \"compilerOptions\": {\n    \"experimentalDecorators\": true,\n    \"emitDecoratorMetadata\": true,\n    \"target\": \"es6\" // or anything newer like esnext\n  }\n}\n```\n\n## Basic Usage\n\n```typescript\nimport {Inject} from \"typescript-ioc\";\n\nclass PersonDAO {\n  @Inject\n  restProxy: PersonRestProxy;\n}\n```\n\nThat's it. You can just call now:\n\n```typescript\nlet personDAO: PersonDAO = new PersonDAO();\n```\n\nAnd the dependencies will be resolved.\n\nYou can also inject constructor parameters, like:\n\n```typescript\nclass PersonService {\n  private personDAO: PersonDAO;\n  constructor( @Inject personDAO: PersonDAO ) {\n    this.personDAO = personDAO;\n  }\n}\n```\n\nand then, if you make an injection to this class, like...\n\n```typescript\nclass PersonController {\n  @Inject\n  private personService: PersonService;\n}\n```\n\nThe container will create an instance of PersonService that receives the PersonDAO from the container on its constructor.\nBut you can still call:\n\n```typescript\nlet personService: PersonService = new PersonService(myPersonDAO);\n```\n\nAnd pass your own instance of PersonDAO to PersonService.\n\nNote that any type with a constructor can be injected.\n\n```typescript\nclass PersonController {\n  @Inject\n  private personService: PersonService;\n\n  @Inject\n  creationTime: Date;\n}\n```\n\n### Inheritance\n\nYou don't have to do anything special to work with sub-types.\n\n```typescript\nabstract class BaseDAO {\n  @Inject\n  creationTime: Date;\n}\n\nclass PersonDAO extends BaseDAO {\n  @Inject\n  private personRestProxy: PersonRestProxy;\n}\n\nclass ProgrammerDAO extends PersonDAO {\n  @Inject\n  private programmerRestProxy: PersonRestProxy;\n}\n```\n\nThe above example will work as expected.\n\n## Scopes\n\nYou can use scopes to manage your instances. We have three pre defined scopes (```Scope.Singleton```, ```Scope.Request``` and ```Scope.Local```), but you can define your own custom Scope.\n\n### @Singleton\n\nAllow just one instance for each type bound to this scope.\n\n```typescript\n@Singleton \nclass PersonService {\n  @Inject\n  private personDAO: PersonDAO;\n}\n\nclass PersonController {\n  @Inject\n  private personService: PersonService;\n\n  @Inject\n  creationTime: Date;\n}\n```\n\nSo, we can create a lot of PersonController instances, but all of them will share the same singleton instance of PersonService\n\n```typescript\nlet controller1: PersonController = new PersonController();\nlet controller2: PersonController = new PersonController();\n\n```\n\n### @InRequestScope\n\nTypes bound to this scope will share instances between the same build context. When you call ```Container.get```, a new build context is created and every container resolution performed will share this context.\n\nFor example:\n\n```typescript\n@InRequestScope\nclass RequestScopeClass {}\n\nclass FirstClass {\n    @Inject\n    public a: RequestScopeClass;\n}\n\nclass SecondClass {\n    @Inject\n    public a: RequestScopeClass;\n    @Inject\n    public b: FirstClass;\n}\n\n```\n\nIn that example, we can expect:\n\n```typescript\nconst secondClass = Container.get(SecondClass);\nexpect(secondClass.a).toEqual(secondClass.b.a);\n```\n\n### Local Scope\n\nThe container will create a new instance every time it will be asked to retrieve objects for types bound to the Local scope.\n\nThe Local scope is the default scope. So you don't need to configure nothing to work with a Local scope. However if you have a Type bound to other scope and want to change it to the Local scope, you can use the ```Scope.Local``` property:\n\n```typescript\n@Singleton\nclass MyType {}\n\nContainer.bind(MyType).scope(Scope.Local);\n```\n\n### Custom Scopes\n To define a new scope, you just have to extend the Scope abstract class:\n\n```typescript\nclass MyScope extends Scope { \n  resolve(factory: ObjectFactory, source:Function, context: BuildContext) {\n    console.log('created by my custom scope.')\n    return factory(context);\n  }\n}\n@Scoped(new MyScope()) \nclass PersonService {\n  @Inject\n  private personDAO: PersonDAO;\n}\n```\n\n## Factories\n\nFactories can be used to create the instances inside the IoC Container.\n\n```typescript\nconst personFactory: ObjectFactory = () =\u003e new PersonService(); \n@Factory(personFactory)\nclass PersonService {\n  @Inject\n  private personDAO: PersonDAO;\n}\n```\n\nThe Factory method will receive the ```BuildContext``` as parameter. So, if you need to retrieve another instance from the container to perform the factory instantiation, you can ask it to the BuildContext. For example:\n\n```typescript\nconst personFactory: ObjectFactory = (context) =\u003e new PersonService(context.resolve(PersonDAO)); \n@Factory(personFactory)\nclass PersonService {\n  constructor(private personDAO: PersonDAO){}\n}\n```\n\n## The @OnlyInstantiableByContainer annotation\nThe @OnlyInstantiableByContainer annotation transforms the annotated class, changing its constructor. So, it will only be able to create new instances for the decorated class through to the IoC Container.\n\nIt is usefull, for example, to avoid direct instantiation of Singletons.\n\n```typescript\n@Singleton \n@OnlyInstantiableByContainer \nclass PersonService {\n  @Inject\n  private personDAO: PersonDAO;\n}\n```\n\nIf anybody try to invoke: \n```typescript\nnew PersonService();\n```\n\nWill prodeuce a TypeError. \n\n## The Container class\n\nYou can also bind types directly to Container resolution.\n\n```typescript\n// it will override any annotation configuration\nContainer.bind(PersonDAO).to(ProgrammerDAO).scope(Scope.Local); \n\n// that will make any injection to Date to return \n// the same instance, created when the first call is executed.\nContainer.bind(Date).to(Date).scope(Scope.Singleton); \n\n// it will ask the IoC Container to retrieve the instance.\nlet personDAO = Container.get(PersonDAO); \n```\n\n```typescript\nclass PersonDAO {\n  @Inject\n  private personRestProxy: PersonRestProxy;\n}\n\nContainer.bind(PersonDAO); \nlet personDAO: PersonDAO = Container.get(PersonDAO); \n// or\nlet otherPersonDAO: PersonDAO = new PersonDAO(); \n// personDAO.personRestProxy is defined. It was resolved by Container.\n```\n\n```typescript\n@OnlyInstantiableByContainer\n@Singleton\nclass PersonDAO {\n}\n\nlet p: PersonDAO = new PersonDAO(); // throws a TypeError.  classes decorated with @OnlyInstantiableByContainer can not be instantiated directly\n\nconst personFactory: ObjectFactory = () =\u003e new PersonDAO();\nContainer.bind(PersonDAO).factory(personFactory); //Works OK\n\nlet personDAO = Container.get(PersonDAO); // Works OK\n```\n\n### @InjectValue decorator and Constants\n\nIt is possible to bind constants to the Container. It is useful for configurations, for example.\n\n```typescript\ninterface Config {\n    dependencyURL: string;\n    port: number;\n}\n\nContainer.bindName('config').to({\n    dependencyURL: 'http://localhost:8080',\n    port: 1234\n});\n```\n\nAnd then you can use the ```@InjectValue``` decorator exactly as you use ```@Inject``` to inject instances.\n\n```typescript\nclass MyService {\n    constructor(@InjectValue('config') public config: Config) { }\n}\n```\n\nIt is possible to inject an internal property from a constant, like:\n\n```typescript\nclass MyService {\n    constructor(@InjectValue('config.dependencyURL') private url: string,\n                @InjectValue('myConfig.otherProperty.item[0].otherURL') private otherURL: string) { }\n}\n```\n\nAnd also to mix constants and other container injections, like:\n\n```typescript\nclass MyService {\n    constructor(@InjectValue('config.dependencyURL') private url: string,\n                @InjectValue('myConfig.otherProperty.item[0].otherURL') private otherURL: string, \n                @Inject private myRepository: MyRepository) { }\n}\n```\n\nValue Injections can be used direclty in class properties:\n\n```typescript\nclass MyService {\n    @InjectValue('config.dependencyURL') \n    private url: string;\n    \n    @InjectValue('myConfig.otherProperty.item[0].otherURL') \n    private otherURL: string;\n    \n    @Inject \n    private myRepository: MyRepository;\n}\n```\n\nOr read directly from the Container:\n\n```typescript\nconst url: string = Container.getValue('config.dependencyURL');\n```\n\nIt is possible to bind an internal property of a constant, like:\n\n```typescript\nContainer.bindName('config.dependencyURL').to('http://anewURL.com');\n```\n\n### Namespaces (Environments)\n\nIt is possible to create specific namespaces with custom configurations and then tell container to use these namespaces.\n\nFor example:\n\n```typescript\nContainer.bindName('config.dependencyURL').to('http://myURL.com');\nconst namespace = Container.namespace('test');\nContainer.bindName('config.dependencyURL').to('http://anewURL.com');\n```\n\nOnly if the namespace ```'test'``` is active, the ```'config.dependencyURL'``` will resolve to ```'http://anewURL.com'```. \n\nTo use the default namespace, just call ```Container.namespace(null)```.\n\nIf you want to remove a namespace, just call ```namespace.remove()```\n\n```typescript\nconst namespace = Container.namespace('test');\nnamespace.remove();\n```\n\nIt is not possible to remove the default namespace.\n\nAn alias called ```'environment'``` is defined for the namespace method: \n\n```typescript\nContainer.namespace('test');\nContainer.environment('test'); // both commands are equivalents\n```\n\nTake a look at [here](#using-namespaces) for more examples of namespaces usage.\n\n### Creating temporary configurations\n\nYou can use snapshot for testing or where you need to temporarily override a binding.\n```typescript\ndescribe('Test Service with Mocks', () =\u003e {\n\n    const snapshot: Snapshot;\n    before(function () {\n        // Store the IoC configuration\n        snapshot = Container.snapshot();\n        \n        // Change the IoC configuration to a mock service.\n        Container.bind(IService).to(MockService);\n    });\n\n    after(function () {\n        // Put the IoC configuration back for IService, so other tests can run.\n        snapshot.restore();\n    });\n\n    it('Should do a test', () =\u003e {\n        // Do some test\n    });\n});\n```\n\n### Importing configurations from external file\n\nYou can put all manual container configurations in an external file and then use the '''Container.configure''' method to import them.\n\nFor example, you can create the ```ioc.config.ts``` file:\n\n```typescript\nimport { MyType, MyTypeImpl, MyType2, MyType2Factory } from './my-types';\nimport { Scope } from 'typescript-ioc';\nimport * as yaml from 'js-yaml';\nimport * as fs from 'fs';\n\nconst config = yaml.safeLoad(fs.readFileSync('service-config.yml', 'utf8'));\n\nexport default [\n  { bind: MyType, to: MyTypeImpl },\n  { \n    bind: MyType2, \n    factory: MyType2Factory, \n    withParams: [Date], \n    scope: Scope.Singleton \n  },\n  { bindName: 'config', to: config }\n];\n\n```\n\nAnd then import the configurations using:\n\n```typescript\nimport { Container } from \"typescript-ioc\";\nimport config from './ioc.config';\n\nContainer.configure(config);\n```\n\nYou need to load the configurations only once, but before you try to use the objects that depends on these files.\n\nYou can create configurations for specific namespaces, like:\n\n```typescript\nimport { MyRepository, MyTestRepository } from './my-types';\nimport * as yaml from 'js-yaml';\nimport * as fs from 'fs';\n\nconst config = yaml.safeLoad(fs.readFileSync('service.config.yml', 'utf8'));\nconst configTest = yaml.safeLoad(fs.readFileSync('service.config-test.yml', 'utf8'));\nconst configProd = yaml.safeLoad(fs.readFileSync('service.config-prod.yml', 'utf8'));\n\nexport default [\n  { bindName: 'config', to: config },\n  { namespace: {\n      test: [\n        { bindName: 'config', to: configTest },\n        { bind: MyRepository, to: MyTestRepository },\n      ],\n      production: [\n        { bindName: 'config', to: configProd }\n      ]\n    }\n  }\n];\n```\n\n## A note about classes and interfaces\n\nTypescript interfaces only exist at development time, to ensure type checking. When compiled, they do not generate runtime code.\nThis ensures good performance, but also means that is not possible to use interfaces as the type of a property being injected. There is no runtime information that could allow any reflection on interface type. Take a look at https://github.com/Microsoft/TypeScript/issues/3628 for more information about this.\n\nSo, this is not supported:\n\n```typescript\ninterface PersonDAO {\n  get(id: string): Person;\n}\n\nclass ProgrammerDAO implements PersonDAO {\n  @Inject\n  private programmerRestProxy: PersonRestProxy;\n\n  get(id: string): Person\n  {\n      // get the person and return it...\n  }\n}\n\nContainer.bind(PersonDAO).to(ProgrammerDAO); // NOT SUPPORTED\n\nclass PersonService {\n  @Inject // NOT SUPPORTED\n  private personDAO: PersonDAO;\n}\n```\nHowever there is no reason for panic. Typescript classes are much more than classes. It could have the same behavior that interfaces on other languages.\n\nSo it is possible to define an abstract class and then implement it as we do with interfaces:\n\n```typescript\nabstract class PersonDAO {\n  abstract get(id: string): Person;\n}\n\nclass ProgrammerDAO implements PersonDAO {\n  @Inject\n  private programmerRestProxy: PersonRestProxy;\n\n  get(id: string): Person\n  {\n      // get the person and return it...\n  }\n}\n\nContainer.bind(PersonDAO).to(ProgrammerDAO); // It works\n\nclass PersonService {\n  @Inject // It works\n  private personDAO: PersonDAO;\n}\n```\n\nThe abstract class in this example has exactly the same semantic that the typescript interface on the previous example. The only difference is that it generates type information into the runtime code, making possible to implement some reflection on it.\n\n## Examples\n\n### Using Container for testing\n\nSome examples of using the container for tests:\n\n```typescript\ndescribe('My Test', () =\u003e {\n    let myService: MyService;\n    beforeAll(() =\u003e {\n        class MockRepository implements AuthenticationRepository {\n          async getAccessToken() {\n            return 'my test token';\n          }\n        }\n        Container.bind(AuthenticationRepository).to(MockRepository)\n        myService = Container.get(MyService);\n    });\n    //...\n});\n```\nor you can configure all your mocks togheter in a mocks.config.ts\n\n```typescript\nclass MockRepository implements AuthenticationRepository {\n  async getAccessToken() {\n    return 'my test token';\n  }\n}\n\nclass OtherMockRepository implements OtherRepository {\n  async doSomething() {\n    return 'done';\n  }\n}\n\nexport default [\n  { bind: AuthenticationRepository, to: MockRepository },\n  { bind: OtherRepository, to: OtherMockRepository }\n];\n```\n\nand then in your test files:\n\n```typescript\nimport mocksConfig from './mocks.config.ts';\n\ndescribe('My Test', () =\u003e {\n    let myService: MyService;\n    beforeAll(() =\u003e {\n        Container.config(mocksConfig);\n        myService = Container.get(MyService);\n    });\n    //...\n});\n```\nor if you want to use the configurations and restore the container after the test:\n\n```typescript\nimport mocksConfig from './mocks.config.ts';\n\ndescribe('My Test', () =\u003e {\n    let myService: MyService;\n    let snaphot: Snaphot;\n    beforeAll(() =\u003e {\n        snapshot = Container.snapshot();\n        Container.config(mocksConfig);\n        myService = Container.get(MyService);\n    });\n\n    afterAll(() =\u003e {\n        snapshot.restore();\n    });\n\n    //...\n});\n```\n\n### Using Namespaces\n\nDefine configurations on a file, like ```ioc.config.ts```:\n\n```typescript\nimport { MyRepository, MyTestRepository } from './my-types';\nimport * as yaml from 'js-yaml';\nimport * as fs from 'fs';\n\nconst config = yaml.safeLoad(fs.readFileSync('service.config.yml', 'utf8'));\nconst configTest = yaml.safeLoad(fs.readFileSync('service.config-test.yml', 'utf8'));\nconst configProd = yaml.safeLoad(fs.readFileSync('service.config-prod.yml', 'utf8'));\n\nexport default [\n  { bindName: 'config', to: config },\n  { env: {\n      test: [\n        { bindName: 'config', to: configTest },\n        { bind: MyRepository, to: MyTestRepository },\n      ],\n      production: [\n        { bindName: 'config', to: configProd }\n      ]\n    }\n  }\n];\n```\nAnd then import the configurations using:\n\n```typescript\nimport { Container } from \"typescript-ioc\";\nimport config from './ioc.config';\n\nContainer.configure(config);\n// Then activate the environment calling the container \nContainer.environment(process.env.NODE_ENV);\n```\n\n## Browser usage\n\nIt was tested with browserify and webpack, but it should work with any other similar tool.\n\nStarting from version 2, this library only works in browsers that supports javascript ES6 '''class'''. If you need to support old ES5 browsers, please use the version 1.2.6 of this library\n\n## Restrictions\n- Circular injections are not supported\n\n## Migrating from previous version\n\nSome breaking changes:\n\n#### ES6 suport \n\nThis library does not support old ES5 code anymore. So, you need to change the target compilation of your code to ```es6``` (or anything else newer, like es2016, es2020, esnext etc)\n\nYour ```tsconfig.json``` needs to include at least:\n ```json\n{\n    \"compilerOptions\": {\n        \"experimentalDecorators\": true,\n        \"emitDecoratorMetadata\": true,\n        \"target\": \"es6\"\n    }\n}\n ```\n\nThis decision was taken to help to solve a lot of bugs with react native and browser environments.\n\nIf you need to support es5 code, you can keep using the 1.2.6 version\n\n#### @AutoWired renamed\n\nA lot of confusion with ```@AutoWired``` motivated us to rename it to ```@OnlyInstantiableByContainer```. It is a big name, but it says exactly what that decorator does. It is completely optional (The container will always work in the same way when instrumenting the types), but it transforms the decorated constructor to avoid that anybody create new instances calling direct a new expression.\n\nSo you need to change all references to ```@AutoWired``` to ```@OnlyInstantiableByContainer```.\n\n#### @Provided @Provides and Provider interface removed\n\nWe changed the name of the interface ```Provider``` to ```ObjectFactory``` and also change the definition of this type to be a simple function signature.\n\nSo, now we have:\n\n```typescript\n// previous version\nconst provider = {\n  get: () =\u003e new MyType()\n};\n\n// new version\nconst factory = () =\u003e new MyType();\n```\n\nFollowing the same design, whe renamed the ```@Provided```decorator to ```@Factory```. \n\n```typescript\n// previous version\n@Provided({\n  get: () =\u003e new MyType()\n})\nclass MyType {\n}\n\n// new version\n@Factory(() =\u003e new MyType())\nclass MyType {\n}\n```\n\nThe ```@Provides``` decorator was removed because it could cause a lot of problems, once it was used in the class that would provide an implementation, that usually was always defined in different files. That forced us to had things like ```ContainerConfig.addSource()``` to scan folders for files. It caused problems in react native, in browser and in some environments like lambda functions.\n\nWe redesigned a new way to load container configurations that does not need to scan folders anymore, removing the problems and improving the performance. Take a look at [```Container.configure``` method](#importing-configurations-from-external-file) for a better option for the old ```@Provides```.\n\n#### Container.snapshot refactored\n\nWe had a minor change in the Snapshot handling. We don't have anymore the public method ```Container.restore(type)```. A safer way to work with snapshots was implemented. Now the ```Container.snapshot``` method returns a snapshot object. That object has a ```restore()``` method.\n\nThe new way:\n\n```typescript\nconst snapshot = Container.snapshot();\nsnapshot.restore();\n```\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fthiagobustamante%2Ftypescript-ioc","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fthiagobustamante%2Ftypescript-ioc","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fthiagobustamante%2Ftypescript-ioc/lists"}