# universal-di

> Universal Dependency Injection for Frontend with Angular-like API

Latest version **1.0.8** (published 2023-12-27) · MIT license · 0 weekly downloads

> **Deprecated.** This package is deprecated.

## Install

```sh
npm install universal-di
pnpm add universal-di
yarn add universal-di
bun add universal-di
```

## Health

**Score 10/100 (F)** — status: deprecated.

Negative: deprecated.

## Facts

| | |
|---|---|
| Version | 1.0.8 |
| Published | 2023-12-27 |
| First published | 2023-12-25 |
| Weekly downloads | 0 |
| License | MIT |
| TypeScript types | bundled |
| Module format | ESM + CommonJS |
| Dependencies | 2 |
| Unpacked size | 52.4 KB |
| Known vulnerabilities | 0 |
| Install scripts | no |
| GitHub stars | 0 |
| Author | Szymon Gracki |
| Maintainers | sgracki |
| Keywords | universal, dependency, injection, solid, react, angular, di |

## Links

- npm: https://www.npmjs.com/package/universal-di
- Repository: https://github.com/szymeo/universal-di
- Issues: https://github.com/szymeo/universal-di/issues
- npm.io page: https://npm.io/package/universal-di

## Dependencies (2)

- [react](https://npm.io/package/react.md) 18.2.0
- [reflect-metadata](https://npm.io/package/reflect-metadata.md) 0.2.1

## Alternatives

- [memory-cache](https://npm.io/package/memory-cache.md) — 795.0K weekly downloads
- [@httptoolkit/proxy-agent](https://npm.io/package/@httptoolkit/proxy-agent.md) — 11.2K weekly downloads
- [express-cache-controller](https://npm.io/package/express-cache-controller.md) — 5.3K weekly downloads
- [http-cache-middleware](https://npm.io/package/http-cache-middleware.md) — 4.5K weekly downloads
- [cache2](https://npm.io/package/cache2.md) — 1.5K weekly downloads

## Recent versions

- 1.0.8 (latest) — 2023-12-27
- 1.0.5 — 2023-12-26
- 1.0.2 — 2023-12-25
- 0.0.2 — 2023-12-25
- 0.0.1 — 2023-12-25

## README

# Universal Dependency Injection
[![MIT License][license-image]][license] [![Build Status][github-action-image]][github-action-url] [![NPM version][npm-version-image]][npm-url] [![Coverage Status][test-coverage-image]][test-coverage-url] [![PRs welcome][contributing-image]][contributing-url]


## Contents

+ [Providing dependencies](#providing-dependencies)
+ [Injecting dependencies](#injecting-a-dependency)
+ [Advanced usage](#advanced-usage)

## Providing Dependencies

Imagine there is a class called ProductService that needs to act as a dependency in a state.

The first step is to add the @Injectable decorator to show that the class can be injected.

```typescript
@Injectable()
class ProductState {
}

@Injectable()
class ProductService {
}
```

Second step is to make it part of your module

```typescript
@Module({
    providers: [
        ProductState,
        ProductService
    ],
})
class ProductModule {
}
```

and then provide to your React DOM

```tsx
const application = new DIApplication(ProductModule);

<DIContextProvider
    injector={application.rootInjector}
>
    <ProductListComponent />
</DIContextProvider>
```

Once you register a provider, you will get singleton instance of this service every time you'd try to inject it.

## Injecting a Dependency

Registered provider can be injected into a class from the same `@Module`

```typescript
@Injectable()
class ProductState {
    constructor(private productService: ProductService) {
    }
}
```

or directly into the React component

```tsx
// ProductListComponent.tsx

const productState = useInjection(ProductState);
```

Besides being a singleton, class is instantiated only when injected, not before.

## Advanced usage

Imagine you are tracking events differently depending on environment

```typescript
interface AnalyticsService {
    track(event: string): void;
}

const ANALYTICS_SERVICE = new InjectionToken<AnalyticsService>('ANALYTICS_SERVICE')
```

After defining the abstraction, next step will be to define implementations

```typescript
@Injectable()
class RealAnalyticsService implements AnalyticsService {
    constructor(
        @Inject(TRACKING_API_URL) private readonly _trackingApiUrl: string,
        private readonly _httpClient: HttpClient,
    ) {
    }

    track(event: string): void {
        this._httpClient.post<void>(this._trackingApiUrl);
    }
}

@Injectable()
class ConsoleAnalyticsService implements AnalyticsService {
    track(event: string): void {
        console.log('[tracking]', event);
    }
}
```

Put together in a `@Module`

```typescript
const TRACKING_API_URL = new InjectionToken<string>('TRACKING_API_URL');

@Module({
    providers: [
        {
            provide: ANALYTICS_SERVICE,
            useClass: isDev() ? ConsoleAnalyticsService : RealAnalyticsService,
        },
        {
            provide: TRACKING_API_URL,
            useValue: '/api/track',
        }
    ],
})
class AnalyticsModule {
}

@Module({
    imports: [
        AnalyticsModule,
    ],
    providers: [
        HttpClient,
    ]
})
class ProductModule {
}
```

Provide to React

```tsx
const application = new DIApplication(ProductModule);

<DIContextProvider
    injector={application.rootInjector}
>
    <ProductListComponent />
</DIContextProvider>
```

And use

```tsx
export function ProductListComponent() {
    const analyticsService = useInjection(ANALYTICS_SERVICE); // AnalyticsService type is inferred here

    useEffect(() => {
        analyticsService.track('browsed-productes');
    }, []);
}
```

### Authors
[![szymeo](https://avatars.githubusercontent.com/u/11583029?v=4&s=40)](https://github.com/szymeo)
[![bartoszswitalski](https://avatars.githubusercontent.com/u/45360754?v=4&s=40)](https://github.com/bartoszswitalski)

[license-image]: https://img.shields.io/badge/license-MIT-blue.svg
[license]: LICENSE.md

[github-action-image]: https://github.com/szymeo/universal-di/actions/workflows/build-and-publish.yml/badge.svg
[github-action-url]: https://github.com/szymeo/universal-di/actions/workflows/build-and-publish.yml

[npm-url]: https://npmjs.org/package/universal-di
[npm-version-image]: https://badge.fury.io/js/universal-di.svg

[test-coverage-url]: https://codecov.io/gh/szymeo/universal-di
[test-coverage-image]: https://codecov.io/gh/szymeo/universal-di/branch/master/graph/badge.svg

[contributing-url]: https://github.com/szymeo/universal-di/blob/master/CONTRIBUTING.md
[contributing-image]: https://img.shields.io/badge/PRs-welcome-brightgreen.svg

---
_Source: https://npm.io/package/universal-di · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
