Skip to content

Commit

Permalink
refactor: disallow inline provider
Browse files Browse the repository at this point in the history
  • Loading branch information
exuanbo committed Oct 10, 2024
1 parent 98b672a commit 3cf8ecb
Show file tree
Hide file tree
Showing 7 changed files with 29 additions and 96 deletions.
30 changes: 0 additions & 30 deletions src/__tests__/index.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,36 +11,6 @@ import {
} from '..'

describe('Features', () => {
it('should prioritize inline provider/config', () => {
const container = new Container()

interface WithValue {
value: string
}
const WithValue = InjectableType<WithValue>('WithValue')

@Injectable(WithValue)
class A implements WithValue {
value = 'A'
}

class B implements WithValue {
value = 'B'
}

class C {
@Inject({
token: WithValue,
useClass: B,
})
content!: WithValue
}

container.register(A)
const c = container.resolve(C)
expect(c.content.value).toBe('B')
})

it('should handle circular dependencies', () => {
const container = new Container()

Expand Down
28 changes: 7 additions & 21 deletions src/__tests__/inject.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,22 +38,6 @@ describe('inject', () => {
expect(a.value).toBeInstanceOf(B)
})

it('should inject with inline provider', () => {
const container = new Container()

class A {
value = inject({
token: B,
useFactory: () => new B(),
})
}

class B {}

const a = container.resolve(A)
expect(a.value).toBeInstanceOf(B)
})

it('should inject with inline config', () => {
const container = new Container()

Expand Down Expand Up @@ -96,18 +80,20 @@ describe('inject', () => {
const B = InjectableType<B>('B')

class A {
value = inject({
token: B,
useFactory: createB,
})
value = inject(B)
}

class BImpl {}
class BImpl implements B {}

function createB() {
return inject(BImpl)
}

container.register({
token: B,
useFactory: createB,
})

const a = container.resolve(A)
expect(a.value).toBeInstanceOf(BImpl)
})
Expand Down
31 changes: 13 additions & 18 deletions src/container.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,8 @@ import {
type InjectionProvider,
isClassProvider,
isFactoryProvider,
isProvider,
isTokenProvider,
isValueProvider,
type Providable,
} from './provider'
import {
type Instantiate,
Expand All @@ -19,7 +17,7 @@ import {
} from './resolution-context'
import type {Resolvable} from './resolvable'
import {InjectionScope} from './scope'
import {type InjectionToken, isConstructor} from './token'
import {type Constructor, type InjectionToken, isConstructor} from './token'

export interface ContainerOptions {
parent?: Container
Expand Down Expand Up @@ -53,12 +51,11 @@ export class Container {
)
}

register<T>(providable: Providable<T>): void {
register<T>(Class: Constructor<T>): void
register<T>(provider: InjectionProvider<T>): void
register<T>(providable: InjectionProvider<T> | Constructor<T>): void {
let provider: InjectionProvider<T>
if (isProvider(providable)) {
provider = providable
}
else {
if (isConstructor(providable)) {
const Class = providable
const metadata = getMetadata(Class)
const token = metadata?.token || Class
Expand All @@ -68,6 +65,9 @@ export class Container {
scope: metadata?.scope,
}
}
else {
provider = providable
}
const token = provider.token
this.providerRegistry.set(token, provider)
}
Expand All @@ -76,16 +76,11 @@ export class Container {
let token: InjectionToken<T>
let provider: InjectionProvider<T> | undefined
if (isConfigLike(resolvable)) {
token = resolvable.token
if (isProvider(resolvable)) {
provider = resolvable
}
else {
const config = resolvable
provider = this.resolveProvider(token)
if (provider && config.scope) {
provider = Object.assign({}, provider, config)
}
const config = resolvable
token = config.token
provider = this.resolveProvider(token)
if (provider && config.scope) {
provider = Object.assign({}, provider, config)
}
}
else {
Expand Down
1 change: 0 additions & 1 deletion src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ export type {
ClassProvider,
FactoryProvider,
InjectionProvider,
Providable,
TokenProvider,
ValueProvider,
} from './provider'
Expand Down
31 changes: 8 additions & 23 deletions src/provider.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,6 @@
import type {InjectionConfig, InjectionConfigLike} from './config'
import type {Resolvable} from './resolvable'
import type {Constructor, InjectionToken} from './token'

export type Providable<T> =
| Constructor<T>
| InjectionProvider<T>

export type InjectionProvider<T = any> =
| ClassProvider<T>
| FactoryProvider<T>
Expand All @@ -29,31 +24,21 @@ export interface ValueProvider<T> extends InjectionConfigLike<T> {
}

/** @internal */
export function isProvider<T>(resolvable: Resolvable<T>) {
return (
isClassProvider(resolvable)
|| isFactoryProvider(resolvable)
|| isTokenProvider(resolvable)
|| isValueProvider(resolvable)
)
}

/** @internal */
export function isClassProvider<T>(resolvable: Resolvable<T>) {
return 'useClass' in resolvable
export function isClassProvider<T>(provider: InjectionProvider<T>) {
return 'useClass' in provider
}

/** @internal */
export function isFactoryProvider<T>(resolvable: Resolvable<T>) {
return 'useFactory' in resolvable
export function isFactoryProvider<T>(provider: InjectionProvider<T>) {
return 'useFactory' in provider
}

/** @internal */
export function isTokenProvider<T>(resolvable: Resolvable<T>) {
return 'useToken' in resolvable
export function isTokenProvider<T>(provider: InjectionProvider<T>) {
return 'useToken' in provider
}

/** @internal */
export function isValueProvider<T>(resolvable: Resolvable<T>) {
return 'useValue' in resolvable
export function isValueProvider<T>(provider: InjectionProvider<T>) {
return 'useValue' in provider
}
2 changes: 0 additions & 2 deletions src/resolvable.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
import type {InjectionConfig} from './config'
import type {InjectionProvider} from './provider'
import type {InjectionToken} from './token'

export type Resolvable<T> =
| InjectionToken<T>
| InjectionConfig<T>
| InjectionProvider<T>
2 changes: 1 addition & 1 deletion src/token.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,6 @@ export function InjectableType<T>(typeName: string): InjectableType<T> {
}

/** @internal */
export function isConstructor<T>(token: InjectionToken<T>) {
export function isConstructor(token: unknown) {
return typeof token == 'function'
}

0 comments on commit 3cf8ecb

Please sign in to comment.