Inversify employs dependency injection similarly to how Angular utilizes TypeScript decorators

Today I made the switch from a js electron project to typescript and found myself wondering about the equivalent of angular's dependency injection. Since Angular Universal is still in its early stages and lacks documentation on using it with electron instead of express, I decided to explore inversify as a potential solution. It seemed like a good fit for my needs, especially considering its lighter weight compared to angular, as I only require dependency injection.

I started experimenting with creating a decorator that would function similarly to the NgModule decorator in Angular.

import { app, Menu, ipcMain, BrowserWindow } from 'electron';
import { Container } from 'inversify';
import { DatabaseService } from 'core/database.service';

function servermodule(data: {providers: Array<any>}) {
  // Some code that instantiates the declarations array classes
  // Do they need to be returned if I don't need a reference?

  let container = new Container();
  return (target: Object) => {
    for(const service of data.providers) {
      container.bind(service).toSelf();
    }
  }

}

This function loops through each entry in providers and binds it to inversify's container object. I plan to use this function as follows, mimicking the usage of angular's decorator.

@servermodule({
  declarations: [
    // Other classes that may receive DatabaseService injection
  ],
  providers: [
    DatabaseService
  ]
})
export class AppModule { ...

The DatabaseService class could look something like this:

 import { injectable } from 'inversify';

 @injectable()
 export class DatabaseService { ...

And it should be injectable in an angular-style manner, for example:

import { inject } from 'inversify';
import { DatabaseService } from './database.service';

export class Models {
  constructor(@inject(DatabaseService) dbService: DatabaseService) { }
}

I'm uncertain about the scope of inversify's container. Does it only exist within the decorator function? Would it be better to initialize it like this?

container = new Container({ autoBindInjectable: true });

How can I properly return it to the AppModule? Is my idea of declaring the classes in the servermodule decorator a viable approach?

Currently, I'm encountering the following error message during tsc compilation and electron execution, even though there are no ts linting errors.

App threw an error during load
Error: Cannot find module 'database.service'

Another idea/question I have is: if I want to include an import attribute in addition to declarations and providers, would it be a good practice to modify the constructor with the decorator and import these classes as well?

Thank you!

Answer №1

Half a year back, I dedicated my time to developing decorator functions for a hierarchical Dependency Injection system that bears resemblance to Angular's. These functions were then packaged together in an npm package named fl-node-di, allowing users to create modules.

FlModule({
  imports: [ AnotherModule ] // includes other FlModules
  providers: [ MyService ] // injects Injectables() into the module's container
  declaration: [] // similar to providers but instantly creates an instance
  exports: [] // shares the Injectable() with the parent's container
})
export class MyModule {}

Another module might appear as follows:

FlModule({
  declarations: [ MyComponent ]
})
export class AnotherModule {}

And a component could be structured in this manner:

@Component()
export class MyComponent {
  constructor (@Inject(MyService) myService: MyService) {}
}

It's important to note the Service. The service is provided in the parent module, establishing a hierarchy.

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

Unable to locate the name 'X' despite importing the name directly above

I'm a little confused about the situation at hand. The name is clearly mentioned right above. https://i.sstatic.net/D0CEV.png Displayed below is the content of storage-backend.interface.ts: export declare interface StorageBackend extends Storage { ...

Modify the selected toggle buttons' color by utilizing the MUI ThemeProvider

I am currently working on customizing the color of selected toggle buttons within my React app using TypeScript and ThemeProvider from @mui/material 5.11.13. Despite my efforts, when a toggle button is selected, it still retains the default color #1976d2, ...

Error message in Angular 2: Unable to locate node module for import

Recently, I encountered an issue while attempting to utilize a specific node module called aws-api-gateway-client Although the installation was successful, I am facing difficulties with importing this module due to an error. Oddly enough, it works seamle ...

The npm build command is triggering an error message that reads "Allocation failed due to ineffective mark-compacts near heap limit."

I'm currently working on a ReactJS/TypeScript project on Windows 10. I've been running into issues when trying to build my TypeScript scripts using the following command: "rimraf ../wwwroot/* && react-scripts-ts build && copyfi ...

Angular's unconventional solution to Firebase

I've been having trouble integrating Firebase with Angular. When I encountered an error stating that firebase.initializeApp is not a function, I hit a roadblock. const firebase = require("firebase"); (Previously, it was written as: import * as fireb ...

An issue occurred in the modal window following the relocation of project files

I encountered an issue with the modal in my Nativescript project after rearranging a few project files, including the modal. I updated the imports and deleted any compiled JavaScript files to ensure that my project could recompile correctly. Although I&ap ...

Azure DevOps pipeline encounters npm authentication failure

After following the official tutorial on deploying an Angular app to ADO pipelines, I encountered a problem with my yaml file: # Node.js with Angular # Build a Node.js project that uses Angular. # Add steps that analyze code, save build artifacts, deploy, ...

Accessing information from a component using ComponentFactoryResolver in Angular 2

I have a grid component and I'm looking to enhance it by incorporating filters for each column. Specifically, I have various filter types for different columns such as simple text input, option filter, date range filter, and more. To achieve this func ...

Retrieving a FirebaseObjectObservable child in Angularfire2 is straightforward

Can you target a specific child of a FirebaseObjectObservable in Angular? Take a look at RcTestAppComponent.save() function below for commented lines. Here is an example: https://github.com/angular/angularfire2/blob/master/docs/3-retrieving-data-as-lists. ...

Creating instance methods in a TypeScript object can be accomplished by defining the methods within the object's class definition. When the object is

As a seasoned Java developer, I've recently been dabbling in TypeScript. Let me introduce you to my user object: export class User { id: string; name: string; email?: string; unit: string; street: string; postalcode: string; ...

Angular: Granting an external module access to a provider

One of the modules I imported provides a service with an optional dependency. Although it being optional didn't affect my application, as it just prevented any errors from occurring when not present. Here's an example: import { FooModule } from ...

How can I use Laravel to enter data using the post method?

I've been struggling with data transfer in my Angular component for a while now, specifically using a post method. Despite extensive research and reading various documents, I haven't been able to find a solution. Can you assist me with this issue ...

Guide on utilizing a provider's variable in another provider within Ionic 2/3

In my code, I have a boolean variable called isConnection that is used to monitor network connection status. This variable is defined in a provider named 'network' and can be set to either true or false in different functions. Now, I need to acc ...

How to Add Multiple Components to app.module.ts in Angular-cli RC 5

I'm currently working on a project using Angular-cli RC5 and I'm facing some challenges creating charts. First, I created a new component called "chart" Then, I created a directive named "line-graph.directive.ts" This is how my folder structur ...

Passing an event between components in AngularDart

Two components, componentA and componentB, are siblings within the structure of componentMother. When componentA is clicked, an event is triggered and handled by event handlerA. How can this event be passed to componentB and handled by event handler B? W ...

The form will not appear if there is no data bound to it

Can anyone help me with displaying the form even when the data is empty in my template? <form class="nobottommargin" *ngIf="details" [formGroup]="form" (ngSubmit)="onSubmit(form.value)" name="template-contactform"> <div class="col-sm-12 nopad ...

What are the steps to display Firestore data on the server instead of the client side?

My objective is to display data on the server side. Expected outcome: the server should render the data. Actual outcome: the data is being rendered by the client instead of the server. The workflow follows this pattern Component -> call Use Case -> ...

.net 6 Attribute routes resulting in a 404 error response

Last week I had a similar question, but now I'm facing an issue with a different controller. I'm baffled as to why I keep getting a 404 error. API Controller... [Route("api/[controller]")] [ApiController] public class FilesController { ...

What is the best way to update the mat-tab when the routeParameters are modified?

I need to reinitialize the mat-tab-group in order to make the first tab active when there is a change in the routeParams. ts file: public index = 0; ngOnInit() { this.subscription = this.route.params.subscribe((routeParams: Params) => { // some ...

Angular 7 is sending out duplicate HTTP requests

Currently, I am implementing an API call to my server in the following component code: formData(username:string, password:string) { if (username == "" || password == "") { this.message = "Fields are empty"; } else { this.loginservi ...