loopbackio / loopbackio/loopback-next

@service(GeocoderProvider) Fails with "No Binding Found" in LoopBack Component

Abierto
#11,062 0 comentarios 0 reacciones 0 asignados Ver en GitHub

Nadie ha tomado este issue todavía.

bug
Lenguaje dominante
TypeScript
Estrellas
5.1k
Forks
1.1k
Merge medio
2 d 21 h
PR fusionados (30 d)
27

Descripción

### Describe the bug

**Problem Description**
@service(GeocoderProvider) Fails with "No Binding Found" in LoopBack Component after overriding the same class via Service booter in application.

❓ **Problem Statement**
You created a custom LoopBack Component named DummyComponent, which declares and registers models, repositories, controllers, and a service (GeocoderProvider):

```ts
export class DummyComponent implements Component {
...
services?: ServiceOrProviderClass[];
...
constructor(
@inject(CoreBindings.APPLICATION_INSTANCE)
private application: Application,
) {
this.services = [GeocoderProvider]; // <-- Intended to register the service
}
}
```

and used in a controller as
```ts
export class TodoController {
constructor(
@repository(TodoRepository)
public todoRepository: TodoRepository,

@service(GeocoderProvider) // <-- This fails
protected geoService: Geocoder,
) {}
}
```
i added DummyComponent in application.ts as
```ts
this.component(DummyComponent);
```

this works fine. but when i override the GeocoderProvider via Service Booter.
this gives me error
```
500 Error: No binding found for GeocoderProvider.
Make sure a service binding is created in context RequestContext-xxxx with serviceInterface (GeocoderProvider).
```
***Steps to reproduce:***
- clone repo https://github.com/Tyagi-Sunny/loopback-next/tree/master
- do npm i
- move to branch ***bug-no-binding-found***
- move to todo example in examples dir - cd examples/todo/
- run npm start
- go to http://localhost:3000
- hit GET /todo

Reason for this error->
@service decorator filters the binding based on a functions
```ts
export function filterByServiceInterface(
serviceInterface: ServiceInterface,
): BindingFilter {
return binding =>
binding.valueConstructor === serviceInterface ||
binding.tagMap[CoreTags.SERVICE_INTERFACE] === serviceInterface;
}
```

and if we explicitly does not provide interface then it uses class itself as interface and used it for comparison. and we end up with two different services that causes comparison to fail and returning no binding found.
As we don't have any options to provide this interface(serviceOptions) via service booter. either we need to Manually bind services after the boot process (defeating the purpose of convention-based discovery)

***Solution:***
I have created a decorator @serviceOptions decorator that allows you to annotate service classes with configuration options metadata. It uses the factory pattern to create decorators with a specific options metadata key.
Then createServiceBinding function is the core registration mechanism that:
- Extracts metadata: Retrieves decorator-defined options from the class
- Merges configurations: Combines decorator metadata with manually passed options (manual options take precedence)
- and rest will be same

### Logs

```shell

```

### Additional information

_No response_

### Reproduction

https://github.com/Tyagi-Sunny/loopback-next/tree/bug-no-binding-found

Guía de contribución

Abrir la guía de contribución

Primeros pasos

  1. Lee el issue completo y luego la guía de contribución del proyecto.
  2. Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
  3. Haz un fork del repositorio y trabaja en una rama.
  4. Abre un pull request que haga referencia al número del issue.

Línea de trabajo

Comienza en la application.ts del ejemplo todo y sigue el registro de Service Booter hasta @service y filterByServiceInterface. Lee la ruta de createServiceBinding y el comportamiento propuesto de los metadatos de @serviceOptions; después, reproduce el fallo con la rama bug-no-binding-found y GET /todo. Se considera terminado cuando el GeocoderProvider sobrescrito se resuelve mediante @service sin un error No binding found.

Escrito por el modelo de indexación a partir del texto del issue.

Evaluación

Stack tecnológico
typescript
Área
backend
Tipo de issue
Error
Dificultad
4/5
Tiempo estimado
3-5 días
Estado de actividad
Estancado
Claridad
Bastante claro
Aptitud para principiantes
35/100

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.