Skip to content

fix: non-reconstructable services are erased when imported #1144

Open
@freshgum-bubbles

Description

@freshgum-bubbles

Description

I found a bug in my fork of TypeDI,
and I thought I'd be a good neighbour by also posting it here.

With the current inheritance code, when a value is imported from
the default container, its value is always set to EMPTY_VALUE.
This breaks non-reconstructable services, which lack either a type
or a factory which allows for re-constructing the service.

Minimal code-snippet showcasing the problem

import 'reflect-metadata';
import { Container, ContainerInstance, Token } from 'typedi';

const myContainer = new ContainerInstance('my-container');

// Set a value on the default container:
const name = new Token<string>();

// Set it with a string value.
// This makes it non-reconstructable, as when it's imported and
// its value is erased, we have no way to reconstruct it (via, e.g.
// a factory or a constructor)
Container.set({ id: name, value: 'Joanna' });

// This breaks:
myContainer.get(name);

StackBlitz Demo

Full error:

Cannot instantiate the requested value for the "Token<UNSET_NAME>" identifier. The related metadata doesn't contain a factory or a type to instantiate.

Expected behavior

If a service can't be reconstructed from a type or a factory, it shouldn't
be erased when imported from the default container.

Actual behavior

The value is always erased.

The problem is caused by this line:

clonedService.value = EMPTY_VALUE;

Metadata

Metadata

Assignees

No one assigned

    Labels

    status: needs triageIssues which needs to be reproduced to be verified report.type: fixIssues describing a broken feature.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions