8
$\begingroup$

SonarLint and others checking tools will warn you if you're injecting services through variable members in Java Spring-Boot:

@Autowired
private DepartementDataset datasetDepartements;

public CogDataset() {
}

you should better inject them through the constructor, they are telling.

private DepartementDataset datasetDepartements;

@Autowired
public CogDataset(DepartementDataset datasetDepartements) {
   this.datasetDepartements = datasetDepartements;
}

I guess it's related to hexagonal architecture, to make the creation of custom components for testing more easy. But I'm not sure of this.

But if you're using a recent version of Angular, you will quickly be warned of the opposite. Are you injecting through a constructor?

export class PresentationComponent {
  constructor(private readonly communeService: CommuneService) {
  }

Your IDE has chances to recommend you to switch to:

export class PresentationComponent {
  private readonly communeService: CommuneService = inject(CommuneService);

  constructor() {
  }

Of course, every programming language makes the choices it wants, but what are the underlying motives of promoting one form or the other?

At the time of language design, how do you pose yourself the problem? What do you consider to make the choice that you will recommend?

$\endgroup$

1 Answer 1

2
$\begingroup$

Angular is written in TypeScript, which is compiled to JavaScript.

The construction injection style requires run-time type information, which is not standard and the TypeScript implementation of it (reflect-metadata) has stopped development due to being superseded by TC39 Decorator Metadata. Notably the new standard does not offer type information.

If Angular wants to stay compatible with vanilla TypeScript & JavaScript in the future, it has to use a style that does not rely solely on type annotations - eg. the inject(Class) solution which does pass the real class object when called.

The Angular documentation states:

Angular's inject function offers more accurate types and better compatibility with standard decorators, compared to constructor-based injection.

That's one possible technical reason, of course there's also the eternal general setter vs. constructor injection debate.

$\endgroup$
2
  • 1
    $\begingroup$ Constructor parameters could also be written like foo: Foo = inject(Foo), just as fields can be ─ I don't see why this would be a significant difference. $\endgroup$ Commented Sep 8 at 10:37
  • $\begingroup$ @kaya3 No, constructor injection means that the DI container passes arguments to the constructor. Assigning a default value from an inject() function call to a constructor parameter just means the constructor can be called without any arguments. Note that function default arguments are not introspectable in JavaScript so it's not possible to do "real" constructor injection with this approach. $\endgroup$ Commented Sep 9 at 12:26

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.