Utilizing inversifyjs for injecting container bindings into an already instantiated object

My goal is to take charge of constructing the object and then using inversify to bind properties that are decorated with @inject.

I initially thought I could utilize the createChild method to bind the type to a value using either toConstantValue or toDynamicValue; however, it seems that neither of these methods handle property binding.

For example:

import "reflect-metadata";
import { Container, inject, injectable } from "inversify";

const container = new Container();
container.bind(Container).toConstantValue(container);

@injectable()
class Foo {
  @inject(Container)
  public container: Container;
}

describe("inversify", () => {
  it("should inject for constructor", () => { //                    PASS
    const c = container.createChild();
    c.bind(Foo).toSelf();
    const result = c.get(Foo);
    expect(result.container).toBeDefined();
  });

  it("should inject for dynamic value", () => { //           FAIL
    const c = container.createChild();
    c.bind(Foo).toDynamicValue(() => new Foo());
    const result = c.get(Foo);
    expect(result.container).toBeDefined();
  });

  it("should inject for constant value", () => { //             FAIL
    const c = container.createChild();
    c.bind(Foo).toConstantValue(new Foo());
    const result = c.get(Foo);
    expect(result.container).toBeDefined();
  });
});

Is there a straightforward way to bind properties without having to defer the object construction to the Container?

Answer №1

It is completely normal for you to be experiencing this behavior as it was intentionally designed this way. Here are some additional insights:

toDynamicValue

In regards to the first test case, the toDynamicValue function is meant to be utilized when InversifyJS is unable to create an instance on its own, such as when injecting something from a third-party library. In these scenarios, InversifyJS leaves it up to you to correctly instantiate the object.

it("should inject for dynamic value", () => {
  const c = container.createChild();
  c.bind(Foo).toDynamicValue(() => new Foo());
  const result = c.get(Foo);
  expect(result.container).toBeDefined();
});

You have the option to make use of the context parameter within the toDynamicValue method to resolve any dependencies:

c.bind(Foo).toDynamicValue((context) => {
    const foo = new Foo();
    const container = context.container.get(Container)
    foo.container = container;
    return foo;
});

Please note: Using

foo.container = context.container
might suffice.

toConstantValue

Regarding the second test case:

it("should inject for const value", () => {
  const c = container.createChild();
  c.bind(Foo).toConstantValue(new Foo());
  const result = c.get(Foo);
  expect(result.container).toBeDefined();
});

As expected, the failure occurs. When utilizing toConstantValue, you must provide a specific value. It is your responsibility to ensure that the value is instantiated correctly. In the example provided, by using new Foo(), InversifyJS does not interfere with the creation process because toConstantValue is specifically designed for cases where variables need to be injected without a constructor (e.g. process.env.SOME_ENV_VAR).

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Encountering an error when setting up a React-TypeScript ContextAPI

I am currently attempting to understand and replicate the functionality of a specific package found at: https://github.com/AlexSegen/react-shopping-cart Working within a React-Typescript project, I have encountered challenges when creating the ProductCont ...

Are there more efficient methods for utilizing local scope when defining a variable?

Having experience in the ML world, I'm used to creating variables with limited scope like this: let myVar = let result1 = doSomething() let result2 = doSomethingElse() result1 + result2 In TypeScript, it seems you can achieve similar sco ...

Setting a TypeScript version in Atom: Step-by-step guide

I'm currently grappling with using a specific version of TypeScript in Atom. For an older project that relies on Backbone, the latest TypeScript version doesn't compile properly, so I need to use an earlier one. The closest solution I've co ...

When using create-react-app with JEST to run tests, TypeScript errors are not displayed

When I write incorrect TypeScript code in my project set up with create-react-app, running tests using npm test does not show any errors in the terminal. Is this normal behavior? It would be helpful to see these errors to avoid writing incorrect TypeScript ...

WebStorm encountering TypeScript error with "nullish coalescing operator"

I am currently facing a problem while using WebStorm with TypeScript v3.7.5. In this particular version, TS introduced the `??` operator. I have implemented it in my project but it seems like WebStorm is not able to understand it and displays an `expressio ...

Exploring an Angular Real-World Example Application on Github - Resolving the Following Bug

my surroundings. export const environment = { production: false, api_url: 'localhost:3306/api' }; my personal server is at localhost:3306 (MAMP) The instructions provided are to edit src/environments/environment.ts in order to ch ...

Error: Serialization of circular structure to JSON not possible in Next.js

I am currently working on creating an API in Next.js to add data into a MySQL database. The issue I am facing is related to a circular reference, but pinpointing it has proven to be challenging. It's worth mentioning that Axios is also being utilized ...

Typescript - neglecting a package that lacks typings

I am considering using an open source package that does not have TypeScript bindings. After checking the linked resource, I was unable to find a solution. Although I attempted to use @ts-ignore, it did not function as expected. Could someone please prov ...

Updating the state in React Native does not occur

I'm facing an issue where I can't seem to update the state using useState while coding in React Native. The component in question is a styled TextInput named SearchField. Can anyone help me figure out what I might be doing wrong that's preve ...

What is the best location for storing test utilities in Next.js applications?

My Next.js (12.x) React (18.x) project includes Jest (28.x) for testing. While my tests in files like __tests__/Product.test.tsx work smoothly, I encountered an issue when trying to reuse some utils across tests: __tests__/util/my-test-helper.ts export fu ...

Unable to locate template while working with Angular 2 in ASP MVC framework

I am currently utilizing angular 2 within ASP.NET MVC. This particular component is referred to as the "other" component: import { Component } from '@angular/core'; @Component({ selector: 'other-app', templateUrl: './app ...

What role does numerical data play in Typescript?

To find the union of types of values associated with numeric keys, the number type must be used. TS PLAYGROUND const animals = ['dog', 'cat', 'hen'] as const type Animal = typeof animals[number] // type Animal = "dog&quo ...

Building an Angular 4 app featuring a customized default landing page and URL parameters functionality

I am in the process of developing a web portal that will be embedded within an iFrame. Below is the code snippet I am using to set up the portal: Routes Configuration const routes: Routes = [ { path: '', redirectTo: '/dash ...

What is the proper way to utilize setTimeout in TypeScript?

Let's take a look at an example of how to use setTimeout in Angular and TypeScript: let timer: number = setTimeout(() => { }, 2000); However, upon compilation, you may encounter the following error message: Error TS2322: Type 'Timeout' ...

Using a static enum in a different class in TypeScript: A guide

After referencing this question and answer on Stack Overflow about setting a static enum inside a TypeScript class, I decided to create my own enum and implement it as a static property in my class. Here is how I did it: /* Input.ts */ enum INPUT_TYPE { T ...

Issue with TypeScript: variable lacks an initializer and is not explicitly assigned within the constructor

Code: class Example { private server: string; constructor() { this.setServer(); } setServer(): void { this.server = 'server'; } } new Example(); Error: ⨯ Unable to compile TypeScript: src/index.ts:309:13 ...

Avoid using the 'exports' keyword when compiling in Typescript

I recently started learning Typescript, although I am proficient in JS. My inquiry pertains to utilizing modules in TS for coding purposes and then excluding the modules when converting to JS. In traditional JS, I segment functionalities into different fi ...

Connect one router to another router within the Oak framework, similar to how it is done in

I have a goal of setting up multiple routers along with a main router that can route requests to the other routers. router.use("/strategy", strategyRoutes); router.use("/account", accountRoutes); The objects router, strategyRoutes, and ...

Troubleshooting the "TypeError: Swiper.initialize is not a function" Issue in React Swiper using TypeScript

Struggling to implement Swiper in a project using nextJs and Typescript. Attempting to modify styles with injectStyle but encountering an error during initialization without knowing how to resolve it. import { useRef, useEffect } from "react"; im ...

There is no universal best common type that can cover all return expressions

While implementing Collection2 in my angular2-meteor project, I noticed that the code snippets from the demo on GitHub always result in a warning message being displayed in the terminal: "No best common type exists among return expressions." Is there a ...