Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Service Container #10

Merged
merged 226 commits into from
Apr 9, 2024
Merged
Changes from 1 commit
Commits
Show all changes
226 commits
Select commit Hold shift + click to select a range
6b06888
Init @aedart/contracts/container submodule
aedart Mar 7, 2024
2cc8659
Init @aedart/support/container submodule
aedart Mar 7, 2024
fa5750e
Init @aedart/container package
aedart Mar 7, 2024
ae2511b
Add path alias to container package source
aedart Mar 7, 2024
3a0f90a
Add container path and reference
aedart Mar 7, 2024
06dc228
Add binding identifier type alias
aedart Mar 8, 2024
330157b
Add DEPENDENCIES symbol
aedart Mar 8, 2024
b5e085f
Add dependencies decorator (incomplete)
aedart Mar 8, 2024
ef5bc25
Export dependencies decorator
aedart Mar 8, 2024
4472c31
Merge branch 'main' into add-service-container
aedart Mar 8, 2024
616100c
Merge branch 'main' into add-service-container
aedart Mar 8, 2024
6fa37f9
Fix JSDoc
aedart Mar 8, 2024
c61d36f
Change Target Meta Repository, add hasAny() method
aedart Mar 8, 2024
4a9bae7
Change release notes
aedart Mar 8, 2024
613bcc0
Add utils for defining class and class method dependencies
aedart Mar 8, 2024
c8cf002
Change release notes
aedart Mar 8, 2024
5579444
Update dependencies
aedart Mar 8, 2024
cd6e40e
Fix typo
aedart Mar 8, 2024
0e86c17
Fix typo
aedart Mar 8, 2024
0c94e59
Add Container Exception and Not Found Exception interfaces
aedart Mar 8, 2024
59167c2
Add notice for Psr / MIT License
aedart Mar 8, 2024
cc3c0c6
Add reference to service container
aedart Mar 8, 2024
e7c1508
Add binding alias
aedart Mar 8, 2024
35d3333
Add FactoryCallback type alias
aedart Mar 8, 2024
b4d4c38
Add Binding Entry interface
aedart Mar 8, 2024
6537cd3
Add Container interface (incomplete)
aedart Mar 8, 2024
d4f700e
Export Binding Entry and Container
aedart Mar 8, 2024
4729310
Improve description of FactoryCallback type alias
aedart Mar 8, 2024
d7a1593
Cleanup
aedart Mar 8, 2024
bb8aea4
Cleanup
aedart Mar 8, 2024
c769df8
Add ClassMethodName and ClassMethodReference type aliases
aedart Mar 11, 2024
c4b6620
Change release notes
aedart Mar 11, 2024
4aa1a39
Add isMethod() util
aedart Mar 11, 2024
f01f52d
Add see also references
aedart Mar 11, 2024
247f660
Add array target case
aedart Mar 11, 2024
b898aea
Change release notes
aedart Mar 11, 2024
94b96ef
Refactor, use isMethod()
aedart Mar 11, 2024
8449693
Add isClassMethodReference() util
aedart Mar 11, 2024
a73d39c
Export isMethod() and isClassMethodReference()
aedart Mar 11, 2024
0fc29aa
Change call()'s method type to ClassMethodReference
aedart Mar 11, 2024
f0d382a
Deprecate ConstructorOrAbstractConstructor type alias
aedart Mar 11, 2024
adcbc02
Replace deprecated ConstructorOrAbstractorConstructor type
aedart Mar 11, 2024
1cc3ae0
Change release notes
aedart Mar 11, 2024
72d2c36
Mark isClassConstructor() as stable
aedart Mar 11, 2024
60a163c
Extract tests into own file for isClassConstructor()
aedart Mar 11, 2024
b425078
Add docs for isClassConstructor
aedart Mar 11, 2024
d519d25
Add see also reference to isClassConstructor()
aedart Mar 11, 2024
0ada395
Mark isCallable() as stable
aedart Mar 11, 2024
c8e840b
Improve desc.
aedart Mar 11, 2024
87a6e6a
Extract isCallable tests into own file
aedart Mar 11, 2024
1d5f28a
Add docs for isCallable
aedart Mar 11, 2024
4eb5749
Add additional cases for built-in classes / objects
aedart Mar 11, 2024
83cb52e
Fix example and improve description of util function
aedart Mar 11, 2024
6c6c712
Improve shown examples
aedart Mar 11, 2024
de56a26
Change release notes
aedart Mar 11, 2024
8f394e5
Add callback type alias
aedart Mar 11, 2024
edde298
Change release notes
aedart Mar 11, 2024
3c2c758
Add support for Callback type in call()
aedart Mar 11, 2024
e0f4abf
Add CallbackWrapper interface
aedart Mar 11, 2024
862b8b1
Change release notes
aedart Mar 11, 2024
30a0962
Export CallbackWrapper interface
aedart Mar 11, 2024
6b77879
Add support for calling a CallbackWrapper instance
aedart Mar 11, 2024
36ef536
Change wrapper, add hasBinding() util method
aedart Mar 12, 2024
1bf0c6a
Add CallbackWrapper (implementation
aedart Mar 12, 2024
47d0603
Change release notes
aedart Mar 12, 2024
1a64695
Shorten error message
aedart Mar 12, 2024
235232b
Add static makeFor() method
aedart Mar 12, 2024
3ef86a3
Add tests for Callback Wrapper
aedart Mar 12, 2024
358e67b
Add isCallbackWrapper() util
aedart Mar 12, 2024
f24e6ac
Change release notes
aedart Mar 12, 2024
eed185a
Add case for calling arrow function with binding
aedart Mar 12, 2024
2476af8
Add docs for callback wrapper
aedart Mar 12, 2024
24830e5
Change default value to undefined for D generic
aedart Mar 12, 2024
0903df9
Change release notes
aedart Mar 12, 2024
e00228b
Add ArbitraryData concern
aedart Mar 12, 2024
fe3cacd
(Re)Fix TS1270 and TS1238 errors
aedart Mar 12, 2024
7085852
Fix missing extends JSDoc
aedart Mar 12, 2024
c846b0a
Cleanup
aedart Mar 12, 2024
19cb91b
Cleanup
aedart Mar 12, 2024
3c73b31
Change CallbackWrapper, use Arbitrary Data concern
aedart Mar 12, 2024
81e5c76
Add test for Arbitrary Data concern usage
aedart Mar 12, 2024
fd87a5c
Fix missing tslib as peer dependency
aedart Mar 12, 2024
1635645
Update dependencies
aedart Mar 12, 2024
d7954f2
Change release notes
aedart Mar 12, 2024
d9940a2
Add JSDoc for call()
aedart Mar 12, 2024
c5db4d3
Add ExtendCallback type alias
aedart Mar 12, 2024
2e3dd0d
Change Container, add extend() method
aedart Mar 12, 2024
f28de53
Add before and after resolving hook callbacks
aedart Mar 12, 2024
40977e8
Fix style
aedart Mar 12, 2024
642e6bd
Deprecate service container symbol
aedart Mar 22, 2024
d2257fe
Fix "not under root dir" TypeScript warning
aedart Mar 22, 2024
a0b7ff2
Fix "not under root dir" TypeScript waning for "support" package
aedart Mar 22, 2024
dbd8445
Add Binding Entry class
aedart Mar 22, 2024
3028410
Export Binding Entry
aedart Mar 22, 2024
19b87cb
Mark support packages as external
aedart Mar 22, 2024
dcea404
Throw TypeError in case of invalid binding value
aedart Mar 22, 2024
4537a68
Expand binding identifier to allow constructors and functions
aedart Mar 22, 2024
d5c7876
Add isBindingIdentifier() util
aedart Mar 22, 2024
93f7326
Change release notes
aedart Mar 22, 2024
7468aca
Change Binding Entry - throw TypeError when identifier is not supported
aedart Mar 22, 2024
c435097
Add tests for binding entry
aedart Mar 22, 2024
adf5784
Add notice about Laravel Service Container
aedart Mar 22, 2024
b7a62a5
Add service container class (incomplete)
aedart Mar 22, 2024
e1da3ea
Export service container
aedart Mar 22, 2024
34c7ac5
Fix isBindingIdentifier() included in export
aedart Mar 22, 2024
fe21d38
Add Container's getInstance() and setInstance() static methods
aedart Mar 22, 2024
9365bbf
Add test for container's singleton instance
aedart Mar 22, 2024
4da5eaf
Change container interface, add isAlias() method
aedart Mar 22, 2024
9629ae3
Add implementation of bind, bindIf, singleton, singletonIf, ... etc
aedart Mar 22, 2024
424eac4
Set public visibility on methods that container interface exposes
aedart Mar 22, 2024
77818f7
Add isShared()
aedart Mar 22, 2024
1b26f80
Add container related errors / exceptions
aedart Mar 22, 2024
7f0fef0
Change build, allow argument overwrites
aedart Mar 22, 2024
9193efc
Add implementation for make() and resolve()
aedart Mar 22, 2024
a442868
Add isBinding() util
aedart Mar 23, 2024
a59a522
Add build() implementation
aedart Mar 23, 2024
f293b71
Add resolve dependencies logic
aedart Mar 24, 2024
b4d6e6b
Reorder internals methods
aedart Mar 24, 2024
b3f18b4
Change args to be optional for call()
aedart Mar 24, 2024
a5bd825
Add call() logic
aedart Mar 24, 2024
0cc1b00
Fix support/misc utils included in dist output
aedart Mar 24, 2024
13b77eb
Fix lint
aedart Mar 24, 2024
d1df977
Fix lint
aedart Mar 24, 2024
584c09a
Fix symbol marked as "type" import
aedart Mar 24, 2024
8c94203
Add "rebound" logic
aedart Mar 25, 2024
29a08f1
Add forgetInstance()
aedart Mar 25, 2024
4344861
Add tests for bind() and singleton() methods
aedart Mar 25, 2024
5c3e58e
Add tests for instance()
aedart Mar 25, 2024
c2e3d8f
Change test, add is "bound" expectation
aedart Mar 25, 2024
7c31cb9
Change tests, add isShared() expectations
aedart Mar 25, 2024
99e0119
Fix semantics
aedart Mar 25, 2024
850cd36
Add tests for alias() and alias related utils
aedart Mar 25, 2024
ebda22e
Add tests for make()
aedart Mar 26, 2024
d782a67
Change order of callback arguments, when callback given as defaultValue
aedart Mar 26, 2024
cdf5822
Add tests for makeOrDefault()
aedart Mar 26, 2024
c573920
Move tests to correct "container" suite
aedart Mar 26, 2024
22e78e2
Improve thrown error when not buildable
aedart Mar 26, 2024
40dfa48
Fix error not configured
aedart Mar 26, 2024
74404ca
Improve circular dependency error handling
aedart Mar 26, 2024
21bba2c
Set target and identifier, when circular dependency error thrown
aedart Mar 26, 2024
56f958d
Add tests for build()
aedart Mar 26, 2024
3576c64
Fix missing JSDoc @type for callback options
aedart Mar 27, 2024
23aff6e
Refactor / Redesign array merge, use a custom "Merger" class
aedart Mar 27, 2024
01cad92
Change release notes
aedart Mar 27, 2024
3dcf9de
Rename to Merger
aedart Mar 27, 2024
9f8e3d9
Add tests for custom merge options and callback
aedart Mar 27, 2024
850bf7b
Add merge options docs, for array merge
aedart Apr 2, 2024
a556cae
Change formatting of arguments
aedart Apr 2, 2024
cb54030
Add array merge options, in object merge
aedart Apr 2, 2024
bf47a89
Change release notes
aedart Apr 2, 2024
90a7f65
Add ref. to array merge options, for object merge
aedart Apr 2, 2024
04bff8c
Fix unable to merge arrays containing functions
aedart Apr 2, 2024
0aff652
Change build test, use classes as dependencies directly
aedart Apr 2, 2024
4432040
Change release notes
aedart Apr 2, 2024
bf01df7
Cleanup
aedart Apr 2, 2024
f8c8ccd
Fix dependencies not resolved for callback-wrapper
aedart Apr 2, 2024
128f0f6
Fix dependencies are not resolved for class method when called
aedart Apr 2, 2024
6216e20
Add tests for call()
aedart Apr 2, 2024
3734629
Add tests for extend()
aedart Apr 2, 2024
a216bce
Change order and semantics of rebound callback arguments
aedart Apr 2, 2024
9c6c376
Add tests for rebinding()
aedart Apr 2, 2024
92de8b0
Refactor forget() to use forgetInstance()
aedart Apr 2, 2024
1cde068
Add tests for forget()
aedart Apr 2, 2024
eaa28a3
Add test for flush()
aedart Apr 2, 2024
dacc5c6
Add test for before() and after()
aedart Apr 2, 2024
6c21cf6
Add Facade abstraction
aedart Apr 3, 2024
ccc68f5
Add service container facade
aedart Apr 3, 2024
c0b1c24
Export facades
aedart Apr 3, 2024
3aaf42b
Add notice for Facade abstraction
aedart Apr 3, 2024
f6922a3
Export facade sub-module
aedart Apr 3, 2024
5e82b15
Mark support/facades as external
aedart Apr 3, 2024
742f939
Fix lint
aedart Apr 3, 2024
2683118
Improve descriptions
aedart Apr 4, 2024
4da4b74
Add resolveIdentifier() method
aedart Apr 4, 2024
0f7cb78
Fix Abstract Class Error argument
aedart Apr 4, 2024
91f582a
Rename destroyFacades() to destroy()
aedart Apr 4, 2024
a562307
Fix private properties are not inherited by child classes
aedart Apr 4, 2024
a9c428e
Init contracts/support/facades submodule
aedart Apr 4, 2024
ec0e814
Add SpyFactoryCallback type alias
aedart Apr 4, 2024
8e3d53d
Export facade related types aliases
aedart Apr 4, 2024
f004bfe
Ignore any type
aedart Apr 4, 2024
2517951
Replace spy callback type with SpyFactoryCallback type alias
aedart Apr 4, 2024
748170b
Improve JSDoc for Container Facade
aedart Apr 4, 2024
6f1d1d7
Add tests for Facade abstraction
aedart Apr 4, 2024
31dd7b8
Change release notes
aedart Apr 4, 2024
3ad91ce
Change from private to protected visibility for class properties
aedart Apr 4, 2024
33ecd57
Change release notes
aedart Apr 4, 2024
54953ec
Change release note
aedart Apr 4, 2024
801d77b
Add Contextual Binding Builder interface
aedart Apr 4, 2024
8ea50a0
Change give(), allow TypeError to be thrown
aedart Apr 4, 2024
af894b7
Add concrete Contextual Binding Builder
aedart Apr 4, 2024
a9a18b3
Mark lodash-es as external dependency
aedart Apr 4, 2024
80fe7d2
Change Container, add support for contextual binding
aedart Apr 4, 2024
87f4ace
Add hasContextualBindings()
aedart Apr 4, 2024
553c9a7
Refactor, use spread arg. for concrete
aedart Apr 4, 2024
2584da6
Add tests for contextual bindings
aedart Apr 4, 2024
63745f3
Clear contextual bindings when flush() is invoked
aedart Apr 5, 2024
e8d368a
Rename _instance to "instance"
aedart Apr 5, 2024
e1e4235
Add description of service container package
aedart Apr 5, 2024
7594ba3
Add Service Container introduction
aedart Apr 5, 2024
9a53949
Add prerequisites for using service container
aedart Apr 5, 2024
463927a
Add how to install guide for service container
aedart Apr 5, 2024
768f2b3
Add guide for how to obtain container instance
aedart Apr 5, 2024
3d2f7ad
Add bindings section (incomplete)
aedart Apr 5, 2024
da04c93
Add how to resolve dependencies guide (incomplete)
aedart Apr 5, 2024
d038486
Add Service Container package docs collection
aedart Apr 5, 2024
0336af9
Add guide on how to define dependencies (incomplete)
aedart Apr 5, 2024
f9b76a1
Add dependencies section
aedart Apr 5, 2024
81f62a5
Add guide for how to define contextual bindings (incomplete)
aedart Apr 5, 2024
acf309c
Add contextual bindings
aedart Apr 5, 2024
5929676
Add make() method section (incomplete)
aedart Apr 5, 2024
9bd052d
Add binding basics, identifiers, concrete types,...etc
aedart Apr 5, 2024
84b11fc
Improve sentence
aedart Apr 8, 2024
ffca9d8
Improve sentence
aedart Apr 8, 2024
5fef3a3
Improve sentences
aedart Apr 8, 2024
eab4403
Improve sentences
aedart Apr 8, 2024
00cabcc
Add guide for defining dependencies on class constructors
aedart Apr 8, 2024
85482ea
Improve sentence
aedart Apr 8, 2024
dc04092
Add guide on how to resolve components and values from container
aedart Apr 8, 2024
6c38127
A guide for contextual bindings
aedart Apr 8, 2024
95becf5
Add Facades doc (incomplete)
aedart Apr 8, 2024
ab22048
Add support/facades collection
aedart Apr 8, 2024
f7f04b0
Refactor Facade, remove the need for resolveIdentifier()
aedart Apr 9, 2024
ed3242a
Fix JSDoc type
aedart Apr 9, 2024
dfafaa5
Refine Facades docs
aedart Apr 9, 2024
b862c57
Highlight Service Container and Facades
aedart Apr 9, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Add call() logic
aedart committed Mar 24, 2024
commit a5bd8255c3fabb60cc0a19533b070d5125534bd9
129 changes: 122 additions & 7 deletions packages/container/src/Container.ts
Original file line number Diff line number Diff line change
@@ -1,22 +1,31 @@
import type {
AfterResolvedCallback,
Alias, BeforeResolvedCallback,
Alias,
BeforeResolvedCallback,
Container as ServiceContainerContract,
ExtendCallback,
FactoryCallback,
Identifier,
Binding
Binding,
DEPENDENCIES
} from "@aedart/contracts/container";
import type {
Callback,
ClassMethodName,
ClassMethodReference,
Constructor,
ConstructorLike
} from "@aedart/contracts";
import type { CallbackWrapper } from "@aedart/contracts/support";
import { hasDependencies, getDependencies } from "@aedart/support/container";
import { getErrorMessage } from "@aedart/support/exceptions";
import { isConstructor, getNameOrDesc } from "@aedart/support/reflections";
import {
isConstructor,
isClassMethodReference,
getNameOrDesc,
hasAllMethods,
} from "@aedart/support/reflections";
import { isCallbackWrapper } from "@aedart/support";
import ContainerError from "./exceptions/ContainerError";
import NotFoundError from "./exceptions/NotFoundError";
import BindingEntry from "./BindingEntry";
@@ -439,16 +448,28 @@ export default class Container implements ServiceContainerContract
* Call given method and inject dependencies if needed
*
* @param {Callback | CallbackWrapper | ClassMethodReference} method
* @param {any[]} args
* @param {any[]} [args]
*
* @return {any}
*
* @throws {ContainerException}
*/
public call(method: Callback | CallbackWrapper | ClassMethodReference, args: any[]): any /* eslint-disable-line @typescript-eslint/no-explicit-any */
public call(method: Callback | CallbackWrapper | ClassMethodReference, args: any[] = []): any /* eslint-disable-line @typescript-eslint/no-explicit-any */
{
// TODO: Implement this...
return null;
if (isClassMethodReference(method)) {
return this.invokeClassMethod(method as ClassMethodReference, args);
}

if (isCallbackWrapper(method)) {
return this.invokeCallbackWrapper(method as CallbackWrapper, args);
}

const type: string = typeof method;
if (type == 'function') {
return this.invokeCallback(method as Callback, args);
}

throw new ContainerError(`Unable to call method: ${type} is not supported`, { cause: { method: method, args: args } });
}

/**
@@ -749,6 +770,100 @@ export default class Container implements ServiceContainerContract
throw new ContainerError(`Unable to resolve "${getNameOrDesc(target as ConstructorLike)}" for binding "${identifier.toString()}": ${reason}`, options);
}
}

/**
* Invokes method in class and returns the methods output
*
* @param {ClassMethodReference} reference
* @param {any[]} [args]
*
* @returns {any}
*
* @throws {ContainerError}
*
* @protected
*/
protected invokeClassMethod(reference: ClassMethodReference, args: any[] = []): any /* eslint-disable-line @typescript-eslint/no-explicit-any */
{
// Build object, when target is a constructor
let target = reference[0];
if (typeof target != 'object') {
target = this.make(target);
}

const name: ClassMethodName<typeof target> = reference[1];
const method: Callback = target[name];

return this.invokeCallback(method.bind(target), args);
}

/**
* Invokes the wrapped callback and returns its output
*
* @param {CallbackWrapper} wrapper
* @param {any[]} [args]
*
* @returns {any}
*
* @throws {ContainerError}
*
* @protected
*/
protected invokeCallbackWrapper(wrapper: CallbackWrapper, args: any[] = []): any /* eslint-disable-line @typescript-eslint/no-explicit-any */
{
// A callback wrapper might already have arguments defined. However,
// if there are any arguments provided here, then the wrapper's arguments must
// be overwritten.
if (args.length != 0) {
wrapper.arguments = args;
}

// But, if no arguments are given, and if the wrapper does not have any arguments,
// then we check if "dependencies" has been defined. If so, they which must be resolved
// and set as arguments for the wrapper's callback.
if (args.length == 0
&& !wrapper.hasArguments()
&& hasAllMethods(wrapper, 'has', 'get')
/* @ts-ignore */
&& wrapper['has'](DEPENDENCIES)
) {
/* @ts-ignore */
const dependencies: Identifier[] = wrapper['get']() ?? [];
const resolved: any[] = []; /* eslint-disable-line @typescript-eslint/no-explicit-any */
for(const identifier of dependencies) {
resolved.push(this.resolveDependency(identifier, wrapper));
}

wrapper.arguments = resolved;
}

// Finally, call the wrapper's callback.
return wrapper.call();
}

/**
* Invokes the given callback and returns its output
*
* @param {Callback} callback
* @param {any[]} [args]
*
* @returns {any}
*
* @throws {ContainerError}
*
* @protected
*/
protected invokeCallback(callback: Callback, args: any[] = []): any /* eslint-disable-line @typescript-eslint/no-explicit-any */
{
// When no arguments are provided, attempt to obtain and resolve dependencies
// for the callback. This will work if the callback is a class method with
// defined dependencies. Otherwise, this will not do anything...
if (args.length == 0 && this.hasDependencies(callback as object)) {
args = this.resolveDependencies(callback as object);
}

return callback(...args);
}

/**
* Obtains and resolves dependencies for given target