Skip to content

Commit e75c2bc

Browse files
authored
Merge pull request #95 from dolittle/fix-tsyringe-di
Fix TSyringe bugs and add support for TypeDI
2 parents a3c540a + 39d261c commit e75c2bc

9 files changed

Lines changed: 96 additions & 8 deletions

File tree

Source/dependencyInversion/Internal/Extensions/DelegatingResolver.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,8 @@ export class DelegatingResolver extends IDynamicResolver {
2121

2222
/** @inheritdoc */
2323
bindUnknownService(serviceIdentifier: interfaces.ServiceIdentifier<unknown>, bindings: Bindings): void {
24-
console.log('Delegating called with', serviceIdentifier);
24+
// TODO: Implement binding multiple dependencies in special delegating resolvers
2525
if (this._services.has(serviceIdentifier)) {
26-
// TODO: Deal with ResolveAll here (probably easy with the context)
2726
bindings.bind(serviceIdentifier).toDynamicValue(() => this._services.get(serviceIdentifier));
2827
}
2928
}
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
// Copyright (c) Dolittle. All rights reserved.
2+
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
3+
4+
import { TypeDIContainer } from '../../Types/TypeDIContainer';
5+
import { IServiceProvider } from '../../IServiceProvider';
6+
import { ServiceIdentifier } from '../../ServiceIdentifier';
7+
8+
/**
9+
* Represents an implementation of {@link IServiceProvider} that uses TypeDI as it's underlying implementation.
10+
*/
11+
export class TypeDIServiceProvider extends IServiceProvider {
12+
/**
13+
* Initialises a new instance of the {@link TypeDIServiceProvider} class.
14+
* @param {TypeDIContainer} _container - The TypeDI container.
15+
*/
16+
constructor(private readonly _container: TypeDIContainer) {
17+
super();
18+
}
19+
20+
/** @inheritdoc */
21+
has(service: ServiceIdentifier<any>): boolean {
22+
return this._container.has(this.toAcceptableIdentifier(service));
23+
}
24+
25+
/** @inheritdoc */
26+
get<T>(service: ServiceIdentifier<T>): T {
27+
return this._container.get<T>(this.toAcceptableIdentifier(service));
28+
}
29+
30+
/** @inheritdoc */
31+
getAsync<T>(service: ServiceIdentifier<T>): Promise<T> {
32+
return Promise.resolve(this._container.get<T>(this.toAcceptableIdentifier(service)));
33+
}
34+
35+
/** @inheritdoc */
36+
getAll<T>(service: ServiceIdentifier<T>): T[] {
37+
return this._container.getMany<T>(this.toAcceptableIdentifier(service));
38+
}
39+
40+
/** @inheritdoc */
41+
getAllAsync<T>(service: ServiceIdentifier<T>): Promise<T[]> {
42+
return Promise.resolve(this._container.getMany<T>(this.toAcceptableIdentifier(service)));
43+
}
44+
45+
private toAcceptableIdentifier<T>(service: ServiceIdentifier<T>): any {
46+
if (typeof service === 'symbol') {
47+
return service.toString();
48+
} else {
49+
return service;
50+
}
51+
}
52+
}

Source/dependencyInversion/Internal/Implementations/_exports.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,4 @@
44
export { InversifyServiceBinder } from './InversifyServiceBinder';
55
export { InversifyServiceProvider } from './InversifyServiceProvider';
66
export { TSyringeServiceProvider } from './TSyringeServiceProvider';
7+
export { TypeDIServiceProvider } from './TypeDIServiceProvider';

Source/dependencyInversion/KnownServiceProviders.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,12 @@
33

44
import { InversifyContainer } from './Types/InversifyContainer';
55
import { TSyringeContainer } from './Types/TSyringeContainer';
6+
import { TypeDIContainer } from './Types/TypeDIContainer';
67

78
/**
89
* Defines the service provider types the Dolittle SDK is compatible with.
910
*/
1011
export type KnownServiceProviders =
1112
InversifyContainer |
12-
TSyringeContainer;
13+
TSyringeContainer |
14+
TypeDIContainer;

Source/dependencyInversion/Types/TSyringeContainer.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,9 @@ export type TSyringeContainer = DependencyContainer;
1414
* @returns {boolean} True if the container is an {@link TSyringeContainer}, false if not.
1515
*/
1616
export const isTSyringeContainer = (container: any): container is TSyringeContainer => {
17-
if (typeof container.isRegistered !== 'function' || container.isRegistered.length !== 2) return false;
18-
if (typeof container.resolve !== 'function' || container.resolve.length !== 2) return false;
19-
if (typeof container.resolveAll !== 'function' || container.resolveAll.length !== 2) return false;
17+
if (typeof container.isRegistered !== 'function' || container.isRegistered.length !== 1) return false;
18+
if (typeof container.resolve !== 'function' || container.resolve.length !== 1) return false;
19+
if (typeof container.resolveAll !== 'function' || container.resolveAll.length !== 1) return false;
2020

2121
return true;
2222
};
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
// Copyright (c) Dolittle. All rights reserved.
2+
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
3+
4+
import { ContainerInstance } from 'typedi';
5+
6+
type TypeDIContainerBase = {
7+
[K in keyof ContainerInstance]: ContainerInstance[K];
8+
};
9+
10+
/**
11+
* Defines the interface of an TypeDI container.
12+
*/
13+
export interface TypeDIContainer extends TypeDIContainerBase {}
14+
15+
/**
16+
* Checks whether or not the provided container is an TypeDI container.
17+
* @param {any} container - The container to check.
18+
* @returns {boolean} True if the container is an {@link TypeDIContainer}, false if not.
19+
*/
20+
export const isTypeDIContainer = (container: any): container is TypeDIContainer => {
21+
if (typeof container.has !== 'function' || container.has.length !== 1) return false;
22+
if (typeof container.get !== 'function' || container.get.length !== 1) return false;
23+
if (typeof container.getMany !== 'function' || container.getMany.length !== 1) return false;
24+
25+
return true;
26+
};

Source/dependencyInversion/Types/_exports.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,4 @@
33

44
export { InversifyContainer, isInversifyContainer } from './InversifyContainer';
55
export { TSyringeContainer, isTSyringeContainer } from './TSyringeContainer';
6+
export { TypeDIContainer, isTypeDIContainer } from './TypeDIContainer';

Source/dependencyInversion/createRootServiceProvider.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ import { isTSyringeContainer } from './Types/TSyringeContainer';
1010
import { IServiceProvider } from './IServiceProvider';
1111
import { KnownServiceProviders } from './KnownServiceProviders';
1212
import { UnknownServiceProviderType } from './UnknownServiceProviderType';
13+
import { isTypeDIContainer } from './Types/TypeDIContainer';
14+
import { TypeDIServiceProvider } from './Internal/Implementations/TypeDIServiceProvider';
1315

1416
/**
1517
* Creates a root {@link IServiceProvider} from the specified service provider.
@@ -26,6 +28,10 @@ export function createRootServiceProvider(serviceProvider: KnownServiceProviders
2628
return new TSyringeServiceProvider(serviceProvider);
2729
}
2830

31+
if (isTypeDIContainer(serviceProvider)) {
32+
return new TypeDIServiceProvider(serviceProvider);
33+
}
34+
2935
const type = Object.getPrototypeOf(serviceProvider).constructor as Constructor<any>;
3036
throw new UnknownServiceProviderType(type);
3137
}

Source/dependencyInversion/package.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@
5151
"winston": "3.3.2"
5252
},
5353
"devDependencies": {
54-
"tsyringe": "4.6.0"
54+
"tsyringe": "4.6.0",
55+
"typedi": "0.10.0"
5556
}
56-
}
57+
}

0 commit comments

Comments
 (0)