diff --git a/.github/workflows/dart.yml b/.github/workflows/dart.yml
index 0126c79..3fa3be2 100644
--- a/.github/workflows/dart.yml
+++ b/.github/workflows/dart.yml
@@ -61,3 +61,27 @@ jobs:
- name: Run tests
run: dart test
+ test_catalyst_builder_container:
+ runs-on: ubuntu-latest
+ defaults:
+ run:
+ working-directory: packages/catalyst_builder_container
+
+ steps:
+ - uses: actions/checkout@v2
+
+ - uses: dart-lang/setup-dart@v1
+ with:
+ sdk: 'stable'
+
+ - name: Install dependencies
+ run: dart pub get
+
+ - name: Verify formatting
+ run: dart format --output=none --set-exit-if-changed lib
+
+ - name: Analyze project source
+ run: dart analyze lib
+
+ - name: Run tests
+ run: dart test
diff --git a/README.md b/README.md
index 78b603a..ad595ec 100644
--- a/README.md
+++ b/README.md
@@ -9,23 +9,17 @@ This is the workspace root, select a specific package for more details.
| Package | Description | Badges |
|-----------------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
-| [`catalyst_builder`](./packages/catalyst_builder) | The builder package. Use this in your root package. | [](https://pub.dartlang.org/packages/catalyst_builder)


 |
+| [`catalyst_builder`](./packages/catalyst_builder) | The builder package. Use this in your root package or plugin package to generate the ServiceContainerPlugin. | [](https://pub.dartlang.org/packages/catalyst_builder)


 |
+| [`catalyst_builder_container`](./packages/catalyst_builder_container) | The container package. Use this package to resolve services from the container. | [](https://pub.dartlang.org/packages/catalyst_builder_container)


 |
| [`catalyst_builder_contracts`](./packages/catalyst_builder_contracts) | The contracts package. Use this in packages that don't need to generate a service provider but provide services that can be resolved. | [](https://pub.dartlang.org/packages/catalyst_builder_contracts)


 |
## Roadmap
-# v4 (Current)
+# v5 (Current)
-| Description | Status |
-|-----------------------------------------------------------------------|--------|
-| Fix build problems with relative dependencies. | ☑️ |
-| Extract the annotations and contracts in a separate package | ☑️ |
-| Remove the service provider subclasses | 🔲 |
-| Make changes to make the `catalyst_builder` package a dev dependency. | 🔲 |
-
-# v5 (Next)
-
-| Description | Status |
-|------------------------------------------------------------|--------|
-| Remove the annotations inside the catalyst_builder_package | ☑️ |
-| Remove the service provider subclasses | 🔲 |
+| Description | Status |
+|---------------------------------------------------------------------------|--------|
+| Remove the annotations inside the catalyst_builder_package | ☑️ |
+| Remove the service provider subclasses | ☑️ |
+| Stop generating the ServiceProvider and create a default ServiceContainer | ☑️ |
+| Add scope support | 🔲 |
diff --git a/packages/catalyst_builder/README.md b/packages/catalyst_builder/README.md
index d89c9b9..ec984df 100644
--- a/packages/catalyst_builder/README.md
+++ b/packages/catalyst_builder/README.md
@@ -1,10 +1,9 @@
-[](https://github.com/mintware-de/catalyst_builder/blob/main/packages/catalyst_builder/LICENSE)
+[](https://github.com/mintware-de/catalyst_builder/blob/main/packages/catalyst_builder/LICENSE)


[](https://pub.dartlang.org/packages/catalyst_builder)


-

# Catalyst Builder
diff --git a/packages/catalyst_builder/build.yaml b/packages/catalyst_builder/build.yaml
index f5dc85b..d6eb15a 100644
--- a/packages/catalyst_builder/build.yaml
+++ b/packages/catalyst_builder/build.yaml
@@ -14,15 +14,6 @@ builders:
- 'catalyst_builder:buildServiceProvider'
- 'catalyst_builder:buildServiceProviderPlugin'
- buildServiceProvider:
- import: 'package:catalyst_builder/src/builder/builders.dart'
- builder_factories:
- - 'createServiceProviderBuilder'
- build_extensions: { '.dart': [ '.catalyst_builder.g.dart' ] }
- build_to: source
- auto_apply: root_package
- required_inputs:
- - '.catalyst_builder.preflight.json'
buildServiceProviderPlugin:
import: 'package:catalyst_builder/src/builder/builders.dart'
builder_factories:
diff --git a/packages/catalyst_builder/example/bin/catalyst_builder_example.dart b/packages/catalyst_builder/example/bin/catalyst_builder_example.dart
index 270b7dc..a830c27 100644
--- a/packages/catalyst_builder/example/bin/catalyst_builder_example.dart
+++ b/packages/catalyst_builder/example/bin/catalyst_builder_example.dart
@@ -1,7 +1,10 @@
+import 'package:catalyst_builder_container/catalyst_builder_container.dart';
import 'package:catalyst_builder_example/example.dart';
void main(List arguments) {
- var provider = ExampleProvider();
+ var provider = ServiceContainer();
+ provider.useExampleProviderPlugin();
+
provider.parameters['sender_username'] = 'Julian';
print('Post parameter set, pre boot');
diff --git a/packages/catalyst_builder/example/lib/example.dart b/packages/catalyst_builder/example/lib/example.dart
index b4e40f0..8fa768c 100644
--- a/packages/catalyst_builder/example/lib/example.dart
+++ b/packages/catalyst_builder/example/lib/example.dart
@@ -4,11 +4,11 @@ import './src/manually_wired_service.dart';
export './public_api.dart';
export './src/manually_wired_service.dart';
-export 'example.catalyst_builder.g.dart';
+export 'example.catalyst_builder.plugin.g.dart';
@Preload()
-@GenerateServiceProvider(
- providerClassName: 'ExampleProvider',
+@GenerateServiceProviderPlugin(
+ pluginClassName: 'ExampleProviderPlugin',
)
@ServiceMap(services: {
ManuallyWiredServiceImplementation: Service(
diff --git a/packages/catalyst_builder/example/pubspec.yaml b/packages/catalyst_builder/example/pubspec.yaml
index ccd7731..d7b3eb4 100644
--- a/packages/catalyst_builder/example/pubspec.yaml
+++ b/packages/catalyst_builder/example/pubspec.yaml
@@ -12,6 +12,8 @@ dependencies:
path: ../../catalyst_builder_contracts
third_party_dependency:
path: ../test/third_party_dependency
+ catalyst_builder_container:
+ path: ../../catalyst_builder_container
dev_dependencies:
lints: ^5.1.1
@@ -23,4 +25,6 @@ dependency_overrides:
catalyst_builder:
path: ../
catalyst_builder_contracts:
- path: ../../catalyst_builder_contracts
\ No newline at end of file
+ path: ../../catalyst_builder_contracts
+ catalyst_builder_container:
+ path: ../../catalyst_builder_container
\ No newline at end of file
diff --git a/packages/catalyst_builder/lib/src/builder/builders.dart b/packages/catalyst_builder/lib/src/builder/builders.dart
index f791b60..8f8e3b1 100644
--- a/packages/catalyst_builder/lib/src/builder/builders.dart
+++ b/packages/catalyst_builder/lib/src/builder/builders.dart
@@ -2,15 +2,10 @@ import 'package:build/build.dart';
import 'preflight_builder.dart';
import 'service_provider_plugin_builder.dart';
-import 'service_provider_builder.dart';
/// Creates the builder for the preflight step
Builder createPreflightBuilder(BuilderOptions options) => PreflightBuilder();
-/// Creates the service provider builder
-Builder createServiceProviderBuilder(BuilderOptions options) =>
- ServiceProviderBuilder();
-
/// Creates the service provider plugin builder
Builder createServiceProviderPluginBuilder(BuilderOptions options) =>
ServiceProviderPluginBuilder();
diff --git a/packages/catalyst_builder/lib/src/builder/dto/dto.dart b/packages/catalyst_builder/lib/src/builder/dto/dto.dart
index eef24ef..4b92e21 100644
--- a/packages/catalyst_builder/lib/src/builder/dto/dto.dart
+++ b/packages/catalyst_builder/lib/src/builder/dto/dto.dart
@@ -3,4 +3,3 @@ export 'extracted_service.dart';
export 'inject_annotation.dart';
export 'preflight_part.dart';
export 'symbol_reference.dart';
-export 'entrypoint.dart';
diff --git a/packages/catalyst_builder/lib/src/builder/dto/entrypoint.dart b/packages/catalyst_builder/lib/src/builder/dto/entrypoint.dart
deleted file mode 100644
index 4b68a85..0000000
--- a/packages/catalyst_builder/lib/src/builder/dto/entrypoint.dart
+++ /dev/null
@@ -1,36 +0,0 @@
-/// Represents a simple symbol reference.
-class Entrypoint {
- /// The name of the service provider class.
- final String providerClassName;
-
- /// The assetId
- final Uri assetId;
-
- /// The name of the plugin class.
- final String pluginClassName;
-
- /// Instantiate a new entrypoint
- const Entrypoint({
- required this.providerClassName,
- required this.assetId,
- required this.pluginClassName,
- });
-
- /// Creates a new instance from the result of [toJson].
- factory Entrypoint.fromJson(Map json) {
- return Entrypoint(
- providerClassName: json['entrypoint'].toString(),
- assetId: Uri.parse(json['assetId'].toString()),
- pluginClassName: json['pluginClassName'].toString(),
- );
- }
-
- /// Dumps the object in a map that can be used in [Entrypoint.fromJson].
- Map toJson() {
- return {
- 'entrypoint': providerClassName,
- 'assetId': assetId.toString(),
- 'pluginClassName': pluginClassName,
- };
- }
-}
diff --git a/packages/catalyst_builder/lib/src/builder/generator/service_provider/fields/applied_plugins.dart b/packages/catalyst_builder/lib/src/builder/generator/service_provider/fields/applied_plugins.dart
deleted file mode 100644
index ab8c5b7..0000000
--- a/packages/catalyst_builder/lib/src/builder/generator/service_provider/fields/applied_plugins.dart
+++ /dev/null
@@ -1,11 +0,0 @@
-import 'package:code_builder/code_builder.dart' as cb;
-
-import '../../symbols.dart';
-
-/// Template for _appliedPlugins
-final appliedPluginsTemplate = cb.Field((f) {
- f
- ..name = appliedPlugins$.symbol
- ..modifier = cb.FieldModifier.final$
- ..assignment = cb.literalList([], serviceProviderPluginT).code;
-});
diff --git a/packages/catalyst_builder/lib/src/builder/generator/service_provider/fields/booted.dart b/packages/catalyst_builder/lib/src/builder/generator/service_provider/fields/booted.dart
deleted file mode 100644
index 0132c8b..0000000
--- a/packages/catalyst_builder/lib/src/builder/generator/service_provider/fields/booted.dart
+++ /dev/null
@@ -1,11 +0,0 @@
-import 'package:code_builder/code_builder.dart' as cb;
-
-import '../../symbols.dart';
-
-/// Template for _booted
-final bootedTemplate = cb.Field((f) {
- f
- ..name = booted$.symbol
- ..modifier = cb.FieldModifier.var$
- ..assignment = cb.literalFalse.code;
-});
diff --git a/packages/catalyst_builder/lib/src/builder/generator/service_provider/fields/expose_map.dart b/packages/catalyst_builder/lib/src/builder/generator/service_provider/fields/expose_map.dart
deleted file mode 100644
index 11ecdf0..0000000
--- a/packages/catalyst_builder/lib/src/builder/generator/service_provider/fields/expose_map.dart
+++ /dev/null
@@ -1,11 +0,0 @@
-import 'package:code_builder/code_builder.dart' as cb;
-
-import '../../symbols.dart';
-
-/// Template for _exposeMap
-final exposeMapTemplate = cb.Field((f) {
- f
- ..name = exposeMap$.symbol
- ..modifier = cb.FieldModifier.final$
- ..assignment = cb.literalMap({}, typeT, typeT).code;
-});
diff --git a/packages/catalyst_builder/lib/src/builder/generator/service_provider/fields/fields.dart b/packages/catalyst_builder/lib/src/builder/generator/service_provider/fields/fields.dart
deleted file mode 100644
index f038a9a..0000000
--- a/packages/catalyst_builder/lib/src/builder/generator/service_provider/fields/fields.dart
+++ /dev/null
@@ -1,8 +0,0 @@
-export 'applied_plugins.dart';
-export 'booted.dart';
-export 'expose_map.dart';
-export 'parameters.dart';
-export 'known_services.dart';
-export 'preloaded_types.dart';
-export 'service_instances.dart';
-export 'services_by_tag.dart';
diff --git a/packages/catalyst_builder/lib/src/builder/generator/service_provider/fields/known_services.dart b/packages/catalyst_builder/lib/src/builder/generator/service_provider/fields/known_services.dart
deleted file mode 100644
index 4a39e9e..0000000
--- a/packages/catalyst_builder/lib/src/builder/generator/service_provider/fields/known_services.dart
+++ /dev/null
@@ -1,11 +0,0 @@
-import 'package:code_builder/code_builder.dart' as cb;
-
-import '../../symbols.dart';
-
-/// Template for _knownServices
-final knownServicesTemplate = cb.Field((f) {
- f
- ..name = knownServices$.symbol
- ..modifier = cb.FieldModifier.final$
- ..assignment = cb.literalMap({}, typeT, serviceDescriptorT).code;
-});
diff --git a/packages/catalyst_builder/lib/src/builder/generator/service_provider/fields/parameters.dart b/packages/catalyst_builder/lib/src/builder/generator/service_provider/fields/parameters.dart
deleted file mode 100644
index 1dac310..0000000
--- a/packages/catalyst_builder/lib/src/builder/generator/service_provider/fields/parameters.dart
+++ /dev/null
@@ -1,12 +0,0 @@
-import 'package:code_builder/code_builder.dart' as cb;
-
-import '../../symbols.dart';
-
-/// Template for parameters
-final parametersTemplate = cb.Field((f) {
- f
- ..name = parameters$.symbol
- ..modifier = cb.FieldModifier.final$
- ..annotations.add(cb.refer('override'))
- ..assignment = cb.literalMap({}, stringT, dynamicT).code;
-});
diff --git a/packages/catalyst_builder/lib/src/builder/generator/service_provider/fields/preloaded_types.dart b/packages/catalyst_builder/lib/src/builder/generator/service_provider/fields/preloaded_types.dart
deleted file mode 100644
index 167f99c..0000000
--- a/packages/catalyst_builder/lib/src/builder/generator/service_provider/fields/preloaded_types.dart
+++ /dev/null
@@ -1,11 +0,0 @@
-import 'package:code_builder/code_builder.dart' as cb;
-
-import '../../symbols.dart';
-
-/// Template for _preloadedTypes
-final preloadedTypesTemplate = cb.Field((f) {
- f
- ..name = preloadedTypes$.symbol
- ..modifier = cb.FieldModifier.final$
- ..assignment = cb.literalList([], typeT).code;
-});
diff --git a/packages/catalyst_builder/lib/src/builder/generator/service_provider/fields/service_instances.dart b/packages/catalyst_builder/lib/src/builder/generator/service_provider/fields/service_instances.dart
deleted file mode 100644
index ceb4359..0000000
--- a/packages/catalyst_builder/lib/src/builder/generator/service_provider/fields/service_instances.dart
+++ /dev/null
@@ -1,10 +0,0 @@
-import 'package:code_builder/code_builder.dart' as cb;
-
-import '../../symbols.dart';
-
-/// Template for _serviceInstances
-final serviceInstancesTemplate = cb.Field((f) {
- f
- ..name = serviceInstances$.symbol
- ..assignment = cb.literalMap({}, typeT, dynamicT).code;
-});
diff --git a/packages/catalyst_builder/lib/src/builder/generator/service_provider/fields/services_by_tag.dart b/packages/catalyst_builder/lib/src/builder/generator/service_provider/fields/services_by_tag.dart
deleted file mode 100644
index abb97e6..0000000
--- a/packages/catalyst_builder/lib/src/builder/generator/service_provider/fields/services_by_tag.dart
+++ /dev/null
@@ -1,11 +0,0 @@
-import 'package:code_builder/code_builder.dart' as cb;
-
-import '../../symbols.dart';
-
-/// Template for _servicesByTag
-final servicesByTagTemplate = cb.Field((f) {
- f
- ..name = servicesByTag$.symbol
- ..modifier = cb.FieldModifier.final$
- ..assignment = cb.literalMap({}, symbolT, listOfT(typeT)).code;
-});
diff --git a/packages/catalyst_builder/lib/src/builder/generator/service_provider/methods/apply_plugin.dart b/packages/catalyst_builder/lib/src/builder/generator/service_provider/methods/apply_plugin.dart
deleted file mode 100644
index bcaf08b..0000000
--- a/packages/catalyst_builder/lib/src/builder/generator/service_provider/methods/apply_plugin.dart
+++ /dev/null
@@ -1,71 +0,0 @@
-import 'package:code_builder/code_builder.dart' as cb;
-
-import '../../helper.dart';
-import '../../symbols.dart';
-
-/// Template for boot()
-cb.Method applyPlugin() {
- return cb.Method((m) {
- final pluginP = cb.refer('plugin');
- var entryV = const cb.Reference('entry');
- var typeV = const cb.Reference('type');
-
- m
- ..name = applyPlugin$.symbol
- ..returns = voidT
- ..requiredParameters.addAll([
- cb.Parameter((p) => p
- ..name = pluginP.symbol!
- ..type = serviceProviderPluginT)
- ])
- ..annotations.add(cb.refer('override'))
- ..body = cb.Block.of([
- // Guard
- IfBuilder(booted$)
- .then(providerAlreadyBootedExceptionT.constInstance([]).thrown)
- .code,
- appliedPlugins$.property('add').call([pluginP]).statement,
- // Add _knownServices
- knownServices$.property('addAll').call([
- pluginP.property(provideKnownServices$.symbol!).call([this$])
- ]).statement,
- // add _exposeMap
- exposeMap$.property('addAll').call(
- [pluginP.property(provideExposes$.symbol!).call([])]).statement,
- preloadedTypes$.property('addAll').call([
- pluginP.property(providePreloadedTypes$.symbol!).call([])
- ]).statement,
-
- // Add tagged services
- ForEachBuilder(
- pluginP
- .property(provideServiceTags$.symbol!)
- .call([]).property('entries'),
- entryV)
- .finalize(cb.CodeExpression(cb.Block.of([
- IfBuilder(servicesByTag$
- .property('containsKey')
- .call([entryV.property('key')]).negate())
- .then(servicesByTag$
- .index(entryV.property('key'))
- .assign(cb.literalList([], typeT)))
- .code,
- ForEachBuilder(entryV.property('value'), typeV)
- .finalize(IfBuilder(servicesByTag$
- .negate()
- .index(entryV.property('key'))
- .nullChecked
- .property('contains')
- .call([typeV]))
- .then(servicesByTag$
- .index(entryV.property('key '))
- .nullChecked
- .property('add')
- .call([typeV]))
- .code)
- .code
- ])).code)
- .code
- ]);
- });
-}
diff --git a/packages/catalyst_builder/lib/src/builder/generator/service_provider/methods/boot.dart b/packages/catalyst_builder/lib/src/builder/generator/service_provider/methods/boot.dart
deleted file mode 100644
index fc49637..0000000
--- a/packages/catalyst_builder/lib/src/builder/generator/service_provider/methods/boot.dart
+++ /dev/null
@@ -1,29 +0,0 @@
-import 'package:code_builder/code_builder.dart' as cb;
-
-import '../../../dto/dto.dart';
-import '../../helper.dart';
-import '../../symbols.dart';
-
-/// Template for boot()
-cb.Method bootTemplate(
- List services,
-) {
- return cb.Method((m) {
- var typeV = const cb.Reference('type');
-
- m
- ..name = boot$.symbol
- ..returns = voidT
- ..annotations.add(cb.refer('override'))
- ..body = cb.Block.of([
- IfBuilder(booted$)
- .then(providerAlreadyBootedExceptionT.constInstance([]).thrown)
- .code,
- assign(booted$, cb.literalTrue).statement,
- ForEachBuilder(preloadedTypes$, typeV)
- .finalize(tryResolveInternal$
- .call([typeV], {}, [dynamicT.type]).statement)
- .code,
- ]);
- });
-}
diff --git a/packages/catalyst_builder/lib/src/builder/generator/service_provider/methods/constructor.dart b/packages/catalyst_builder/lib/src/builder/generator/service_provider/methods/constructor.dart
deleted file mode 100644
index bcd77a1..0000000
--- a/packages/catalyst_builder/lib/src/builder/generator/service_provider/methods/constructor.dart
+++ /dev/null
@@ -1,11 +0,0 @@
-import 'package:code_builder/code_builder.dart' as cb;
-
-import '../../symbols.dart';
-
-/// Template for the constructor
-cb.Constructor buildProviderConstructor(String pluginClassName) {
- return cb.Constructor((ctor) => ctor
- ..body = cb.Block.of([
- applyPlugin$.call([cb.refer(pluginClassName).call([])]).statement,
- ]));
-}
diff --git a/packages/catalyst_builder/lib/src/builder/generator/service_provider/methods/enhance.dart b/packages/catalyst_builder/lib/src/builder/generator/service_provider/methods/enhance.dart
deleted file mode 100644
index ce73cbf..0000000
--- a/packages/catalyst_builder/lib/src/builder/generator/service_provider/methods/enhance.dart
+++ /dev/null
@@ -1,105 +0,0 @@
-import 'package:code_builder/code_builder.dart' as cb;
-
-import '../../helper.dart';
-import '../../symbols.dart';
-
-/// Template for ServiceProvider enhance({
-/// List<ServiceDescriptor> services = const [],
-/// Map<String, dynamic> parameters = const {},
-/// });
-cb.Method enhanceTemplate(String providerClassName) {
- return cb.Method((m) {
- var servicesP = const cb.Reference('services');
- var parametersP = const cb.Reference('parameters');
-
- var serviceV = const cb.Reference('service');
- var enhancedV = const cb.Reference('enhanced');
- var pluginV = const cb.Reference('plugin');
-
- m
- ..annotations.add(cb.refer('override'))
- ..name = enhance$.symbol
- ..returns = serviceProviderT
- ..optionalParameters.addAll([
- cb.Parameter(
- (p) => p
- ..name = servicesP.symbol!
- ..named = true
- ..type = ((cb.TypeReferenceBuilder()
- ..symbol = 'List'
- ..types.add(lazyServiceDescriptorT))
- .build())
- ..defaultTo = cb.literalConstList([], lazyServiceDescriptorT).code,
- ),
- cb.Parameter(
- (p) => p
- ..name = parametersP.symbol!
- ..named = true
- ..type = ((cb.TypeReferenceBuilder()
- ..symbol = 'Map'
- ..types.addAll([stringT, dynamicT]))
- .build())
- ..defaultTo = cb.literalConstMap({}, stringT, dynamicT).code,
- ),
- ])
- ..body = cb.Block.of([
- ensureBoot$.call([]).statement,
- initVar(enhancedV, cb.refer(providerClassName).newInstance([])),
- ForEachBuilder(appliedPlugins$, pluginV)
- .finalize(enhancedV
- .property(applyPlugin$.symbol!)
- .call([pluginV]).statement)
- .code,
- enhancedV
- .property(serviceInstances$.symbol!)
- .assign(serviceInstances$)
- .statement,
- _addKnownServices(enhancedV),
- enhancedV
- .property(exposeMap$.symbol!)
- .property('addAll')
- .call([exposeMap$]).statement,
- ForEachBuilder(servicesP, serviceV)
- .finalize(enhancedV.property(registerInternal$.symbol!).call([
- serviceV.property('returnType'),
- serviceV.property('factory'),
- serviceV.property('service'),
- ]).statement)
- .code,
- enhancedV
- .property(parameters$.symbol!)
- .property('addAll')
- .call([this$.property(parameters$.symbol!)]).statement,
- enhancedV
- .property(parameters$.symbol!)
- .property('addAll')
- .call([parameters$]).statement,
- enhancedV.property(booted$.symbol!).assign(cb.literalTrue).statement,
- enhancedV.returned.statement,
- ]);
- });
-}
-
-/// Adds missing _knownServices to the enhanced provider _knownServices map.
-cb.Code _addKnownServices(cb.Reference enhancedV) {
- var elV = const cb.Reference('el');
-
- return enhancedV.property(knownServices$.symbol!).property('addAll').call([
- cb.refer('Map').property('fromEntries').call([
- knownServices$.property('entries').property('where').call([
- (cb.MethodBuilder()
- ..lambda = true
- ..requiredParameters.addAll([
- cb.Parameter((b) => b..name = elV.symbol!),
- ])
- ..body = enhancedV
- .negate()
- .property(knownServices$.symbol!)
- .property('containsKey')
- .call([elV.property('key')]).code)
- .build()
- .closure
- ])
- ])
- ]).statement;
-}
diff --git a/packages/catalyst_builder/lib/src/builder/generator/service_provider/methods/ensure_booted.dart b/packages/catalyst_builder/lib/src/builder/generator/service_provider/methods/ensure_booted.dart
deleted file mode 100644
index 8cf82c4..0000000
--- a/packages/catalyst_builder/lib/src/builder/generator/service_provider/methods/ensure_booted.dart
+++ /dev/null
@@ -1,16 +0,0 @@
-import 'package:code_builder/code_builder.dart' as cb;
-
-import '../../helper.dart';
-import '../../symbols.dart';
-
-/// Template for _ensureBooted
-final ensureBootedTemplate = cb.Method((m) {
- m
- ..name = ensureBoot$.symbol
- ..returns = voidT
- ..body = cb.Block.of([
- IfBuilder(booted$.equalTo(cb.literalFalse))
- .then(providerNotBootedExceptionT.constInstance([]).thrown)
- .code,
- ]);
-});
diff --git a/packages/catalyst_builder/lib/src/builder/generator/service_provider/methods/has.dart b/packages/catalyst_builder/lib/src/builder/generator/service_provider/methods/has.dart
deleted file mode 100644
index e47e69a..0000000
--- a/packages/catalyst_builder/lib/src/builder/generator/service_provider/methods/has.dart
+++ /dev/null
@@ -1,35 +0,0 @@
-import 'package:code_builder/code_builder.dart' as cb;
-
-import '../../helper.dart';
-import '../../symbols.dart';
-
-/// Template for has<T>([Type t = null])
-final hasTemplate = cb.Method((m) {
- var typeTP = cb.TypeReference((b) => b..symbol = 'T');
-
- var typeP = const cb.Reference('type');
-
- var lookupType$ = cb.refer('lookupType');
-
- m
- ..annotations.add(cb.refer('override'))
- ..name = has$.symbol
- ..types.add(typeTP)
- ..returns = boolT
- ..optionalParameters.addAll([
- cb.Parameter(
- (p) => p
- ..name = typeP.symbol!
- ..type = nullable(typeT)
- ..required = false,
- )
- ])
- ..body = cb.Block.of([
- initVar(lookupType$, typeP.ifNullThen(typeTP)),
- knownServices$
- .property('containsKey')
- .call([exposeMap$[lookupType$].ifNullThen(lookupType$)])
- .returned
- .statement,
- ]);
-});
diff --git a/packages/catalyst_builder/lib/src/builder/generator/service_provider/methods/methods.dart b/packages/catalyst_builder/lib/src/builder/generator/service_provider/methods/methods.dart
index 79f8761..04ee978 100644
--- a/packages/catalyst_builder/lib/src/builder/generator/service_provider/methods/methods.dart
+++ b/packages/catalyst_builder/lib/src/builder/generator/service_provider/methods/methods.dart
@@ -1,18 +1,4 @@
-export 'apply_plugin.dart';
-export 'boot.dart';
-export 'constructor.dart';
-export 'enhance.dart';
-export 'ensure_booted.dart';
-export 'has.dart';
export 'provide_exposes.dart';
export 'provide_known_services.dart';
export 'provide_preloaded_types.dart';
export 'provide_service_tags.dart';
-export 'register.dart';
-export 'register_internal.dart';
-export 'resolve.dart';
-export 'resolve_by_tag.dart';
-export 'resolve_or_get_parameter.dart';
-export 'try_resolve.dart';
-export 'try_resolve_internal.dart';
-export 'try_resolve_or_get_parameter.dart';
diff --git a/packages/catalyst_builder/lib/src/builder/generator/service_provider/methods/register.dart b/packages/catalyst_builder/lib/src/builder/generator/service_provider/methods/register.dart
deleted file mode 100644
index e7c492e..0000000
--- a/packages/catalyst_builder/lib/src/builder/generator/service_provider/methods/register.dart
+++ /dev/null
@@ -1,43 +0,0 @@
-import 'package:code_builder/code_builder.dart' as cb;
-
-import '../../symbols.dart';
-
-/// Template for register<T>(
-/// Service service,
-/// T Function(ServiceProvider) factory
-/// )
-final registerTemplate = cb.Method((m) {
- var typeTP = cb.TypeReference((b) => b..symbol = 'T');
-
- var serviceP = const cb.Reference('service');
- var factoryP = const cb.Reference('factory');
-
- m
- ..annotations.add(cb.refer('override'))
- ..name = register$.symbol
- ..types.add(typeTP)
- ..returns = voidT
- ..requiredParameters.addAll([
- cb.Parameter(
- (p) => p
- ..name = factoryP.symbol!
- ..type = cb.FunctionType((b) => b
- ..returnType = typeTP
- ..requiredParameters.addAll([
- serviceProviderT,
- ]))
- ..required = false,
- )
- ])
- ..optionalParameters.addAll([
- cb.Parameter(
- (p) => p
- ..name = serviceP.symbol!
- ..type = serviceT
- ..defaultTo = serviceT.constInstance([]).code,
- ),
- ])
- ..body = cb.Block.of([
- registerInternal$.call([typeTP, factoryP, serviceP]).statement,
- ]);
-});
diff --git a/packages/catalyst_builder/lib/src/builder/generator/service_provider/methods/register_internal.dart b/packages/catalyst_builder/lib/src/builder/generator/service_provider/methods/register_internal.dart
deleted file mode 100644
index 31c1141..0000000
--- a/packages/catalyst_builder/lib/src/builder/generator/service_provider/methods/register_internal.dart
+++ /dev/null
@@ -1,67 +0,0 @@
-import 'package:code_builder/code_builder.dart' as cb;
-
-import '../../helper.dart';
-import '../../symbols.dart';
-
-/// Template for _registerInternal<T>(
-/// Type tReal,
-/// Service service,
-/// T Function(ServiceProvider) factory
-/// )
-final registerInternalTemplate = cb.Method((m) {
- var typeTP = cb.TypeReference((b) => b..symbol = 'T');
-
- var tRealP = const cb.Reference('tReal');
- var serviceP = const cb.Reference('service');
- var factoryP = const cb.Reference('factory');
- var exposeAsP = const cb.Reference('exposeAs');
-
- m
- ..name = registerInternal$.symbol
- ..types.add(typeTP)
- ..returns = voidT
- ..requiredParameters.addAll([
- cb.Parameter(
- (p) => p
- ..name = tRealP.symbol!
- ..type = typeT
- ..required = false,
- ),
- cb.Parameter(
- (p) => p
- ..name = factoryP.symbol!
- ..type = cb.FunctionType((b) => b
- ..returnType = typeTP
- ..requiredParameters.addAll([
- serviceProviderT,
- ]))
- ..required = false,
- )
- ])
- ..optionalParameters.addAll([
- cb.Parameter(
- (p) => p
- ..name = serviceP.symbol!
- ..type = serviceT
- ..defaultTo = serviceT.constInstance([]).code,
- ),
- ])
- ..body = cb.Block.of([
- knownServices$[tRealP]
- .assign(serviceDescriptorT.call([
- serviceP,
- cb.Method(
- (mb) => mb
- ..lambda = true
- ..body = factoryP.call([this$]).code,
- ).closure,
- ]))
- .statement,
- IfBuilder(serviceP.property(exposeAsP.symbol!).notEqualTo(cb.literalNull))
- .then(
- exposeMap$[serviceP.property(exposeAsP.symbol!).nullChecked]
- .assign(tRealP.expression),
- )
- .code
- ]);
-});
diff --git a/packages/catalyst_builder/lib/src/builder/generator/service_provider/methods/resolve.dart b/packages/catalyst_builder/lib/src/builder/generator/service_provider/methods/resolve.dart
deleted file mode 100644
index 03d9844..0000000
--- a/packages/catalyst_builder/lib/src/builder/generator/service_provider/methods/resolve.dart
+++ /dev/null
@@ -1,23 +0,0 @@
-import 'package:code_builder/code_builder.dart' as cb;
-
-import '../../helper.dart';
-import '../../symbols.dart';
-
-/// Template for resolve<T>()
-final resolveTemplate = cb.Method((m) {
- var typeT = cb.TypeReference((b) => b..symbol = 'T');
-
- var resolved$ = cb.refer('resolved');
-
- m
- ..annotations.add(cb.refer('override'))
- ..name = resolve$.symbol
- ..types.add(typeT)
- ..body = cb.Block.of([
- ensureBoot$.call([]).statement,
- initVar(resolved$, tryResolve$.call([], {}, [typeT])),
- IfBuilder(resolved$.notEqualTo(cb.literalNull)).thenReturn(resolved$),
- serviceNotFoundExceptionT.call([typeT]).thrown.statement,
- ])
- ..returns = typeT;
-});
diff --git a/packages/catalyst_builder/lib/src/builder/generator/service_provider/methods/resolve_by_tag.dart b/packages/catalyst_builder/lib/src/builder/generator/service_provider/methods/resolve_by_tag.dart
deleted file mode 100644
index 5d0f9b1..0000000
--- a/packages/catalyst_builder/lib/src/builder/generator/service_provider/methods/resolve_by_tag.dart
+++ /dev/null
@@ -1,35 +0,0 @@
-import 'package:catalyst_builder/src/builder/generator/helper.dart';
-import 'package:code_builder/code_builder.dart' as cb;
-
-import '../../symbols.dart';
-
-/// Template for resolveByTagTemplate(Symbol tag)
-final resolveByTagTemplate = cb.Method((m) {
- var tagP = cb.refer('tag');
- var servicesV = cb.refer('services');
- var svcV = cb.refer('svc');
- m
- ..annotations.add(cb.refer('override'))
- ..name = resolveByTag$.symbol
- ..requiredParameters.addAll([
- cb.Parameter(
- (p) => p
- ..name = tagP.symbol!
- ..type = symbolT,
- )
- ])
- ..body = cb.Block.of([
- initVar(servicesV, cb.literalList([], dynamicT)),
- IfBuilder(servicesByTag$.property('containsKey').call([tagP]).negate())
- .thenReturn(servicesV),
- ForEachBuilder(servicesByTag$[tagP].nullChecked, svcV)
- .finalize(
- servicesV.property('add').call([
- tryResolveInternal$.call([svcV]).asA(dynamicT)
- ]).statement,
- )
- .code,
- servicesV.returned.statement
- ])
- ..returns = listOfT(dynamicT);
-});
diff --git a/packages/catalyst_builder/lib/src/builder/generator/service_provider/methods/resolve_or_get_parameter.dart b/packages/catalyst_builder/lib/src/builder/generator/service_provider/methods/resolve_or_get_parameter.dart
deleted file mode 100644
index a4b4894..0000000
--- a/packages/catalyst_builder/lib/src/builder/generator/service_provider/methods/resolve_or_get_parameter.dart
+++ /dev/null
@@ -1,54 +0,0 @@
-import 'package:code_builder/code_builder.dart' as cb;
-
-import '../../helper.dart';
-import '../../symbols.dart';
-
-/// Template for _resolveOrGetParameter()
-final resolveOrGetParameterTemplate = cb.Method((m) {
- var typeT = cb.TypeReference((b) => b..symbol = 'T');
-
- var paramParamName$ = cb.refer('param');
- var paramBoundParameter = cb.refer('parameter');
- var paramRequiredBy$ = cb.refer('requiredBy');
-
- var resolved$ = cb.refer('resolved');
- var body = cb.Block.of([
- initVar(
- resolved$,
- tryResolveOrGetParameter$.call(
- [paramBoundParameter.ifNullThen(paramParamName$)],
- {},
- [typeT],
- )),
- IfBuilder(resolved$.equalTo(cb.literalNull))
- .then(dependencyNotFoundExceptionT.call([
- paramRequiredBy$,
- paramParamName$,
- serviceNotFoundExceptionT.call([typeT])
- ]).thrown)
- .code,
- resolved$.returned.statement,
- ]);
-
- m
- ..name = resolveOrGetParameter$.symbol
- ..annotations.add(cb.refer('override'))
- ..requiredParameters.addAll([
- cb.Parameter((p) => p
- ..name = paramRequiredBy$.symbol!
- ..required = false
- ..type = cb.refer('Type')),
- cb.Parameter((p) => p
- ..name = paramParamName$.symbol!
- ..type = cb.refer('String')),
- ])
- ..optionalParameters.addAll([
- cb.Parameter((p) => p
- ..name = paramBoundParameter.symbol!
- ..required = false
- ..type = cb.refer('String?')),
- ])
- ..body = body
- ..types.add(typeT)
- ..returns = typeT;
-});
diff --git a/packages/catalyst_builder/lib/src/builder/generator/service_provider/methods/try_resolve.dart b/packages/catalyst_builder/lib/src/builder/generator/service_provider/methods/try_resolve.dart
deleted file mode 100644
index 52f12e2..0000000
--- a/packages/catalyst_builder/lib/src/builder/generator/service_provider/methods/try_resolve.dart
+++ /dev/null
@@ -1,21 +0,0 @@
-import 'package:code_builder/code_builder.dart' as cb;
-
-import '../../symbols.dart';
-
-/// Template for tryResolve<T>()
-final tryResolveTemplate = cb.Method((m) {
- var typeT = cb.TypeReference((b) => b..symbol = 'T');
-
- var nullableTypeT = cb.TypeReference((b) => b
- ..symbol = typeT.symbol
- ..isNullable = true);
-
- m
- ..annotations.add(cb.refer('override'))
- ..name = tryResolve$.symbol
- ..types.add(typeT)
- ..returns = nullableTypeT
- ..body = cb.Block.of([
- tryResolveInternal$.call([typeT], {}, [typeT]).returned.statement,
- ]);
-});
diff --git a/packages/catalyst_builder/lib/src/builder/generator/service_provider/methods/try_resolve_internal.dart b/packages/catalyst_builder/lib/src/builder/generator/service_provider/methods/try_resolve_internal.dart
deleted file mode 100644
index 7258891..0000000
--- a/packages/catalyst_builder/lib/src/builder/generator/service_provider/methods/try_resolve_internal.dart
+++ /dev/null
@@ -1,50 +0,0 @@
-import 'package:code_builder/code_builder.dart' as cb;
-
-import '../../helper.dart';
-import '../../symbols.dart';
-
-/// Template for _tryResolveInternal<T>(Type t)
-final tryResolveInternalTemplate = cb.Method((m) {
- var typeT = cb.TypeReference((b) => b..symbol = 'T');
-
- var singletonLifeTime$ = cb.refer('ServiceLifetime.singleton', rootPackage);
-
- var descriptor$ = cb.refer('descriptor');
-
- var nullableTypeT = cb.TypeReference((b) => b
- ..symbol = typeT.symbol
- ..isNullable = true);
-
- var exposedType$ = cb.refer('exposedType');
- var instance$ = cb.refer('instance');
-
- var typeP = cb.refer('t');
-
- m
- ..name = tryResolveInternal$.symbol
- ..types.add(typeT)
- ..requiredParameters.add(cb.Parameter(
- (p) => p
- ..name = typeP.symbol!
- ..type = cb.refer('Type'),
- ))
- ..returns = nullableTypeT
- ..body = cb.Block.of([
- ensureBoot$.call([]).statement,
- initVar(exposedType$, exposeMap$[typeP]),
- fallbackIfNull(exposedType$, typeP).statement,
- IfBuilder(
- serviceInstances$.property('containsKey').call([exposedType$]),
- ).thenReturn(serviceInstances$[exposedType$].asA(nullableTypeT)),
- initVar(descriptor$, knownServices$[exposedType$]),
- IfBuilder(descriptor$.equalTo(cb.literalNull)).thenReturn(cb.literalNull),
- initVar(instance$, descriptor$.property('produce').call([])),
- IfBuilder(descriptor$
- .property('service')
- .property('lifetime')
- .equalTo(singletonLifeTime$))
- .then(assign(serviceInstances$[exposedType$], instance$))
- .code,
- instance$.asA(nullableTypeT).returned.statement,
- ]);
-});
diff --git a/packages/catalyst_builder/lib/src/builder/generator/service_provider/methods/try_resolve_or_get_parameter.dart b/packages/catalyst_builder/lib/src/builder/generator/service_provider/methods/try_resolve_or_get_parameter.dart
deleted file mode 100644
index fa93593..0000000
--- a/packages/catalyst_builder/lib/src/builder/generator/service_provider/methods/try_resolve_or_get_parameter.dart
+++ /dev/null
@@ -1,36 +0,0 @@
-import 'package:code_builder/code_builder.dart' as cb;
-
-import '../../helper.dart';
-import '../../symbols.dart';
-
-/// Template for _tryResolveOrGetParameter()
-final tryResolveOrGetParameterTemplate = cb.Method((m) {
- var typeT = cb.TypeReference((b) => b..symbol = 'T');
- var nullableTypeT = cb.TypeReference((b) => b
- ..symbol = typeT.symbol
- ..isNullable = true);
-
- var paramB$ = cb.refer('b');
- var resolvedService$ = cb.refer('resolvedService');
-
- var body = cb.Block.of([
- initVar(resolvedService$, tryResolve$.call([], {}, [typeT])),
- IfBuilder(resolvedService$.notEqualTo(cb.literalNull))
- .thenReturn(resolvedService$),
- IfBuilder(parameters$[paramB$].isA(typeT))
- .thenReturn(parameters$[paramB$].asA(typeT)),
- cb.literalNull.returned.statement,
- ]);
-
- m
- ..name = tryResolveOrGetParameter$.symbol
- ..annotations.add(cb.refer('override'))
- ..requiredParameters.addAll([
- cb.Parameter((p) => p
- ..name = paramB$.symbol!
- ..type = stringT)
- ])
- ..body = body
- ..types.add(typeT)
- ..returns = nullableTypeT;
-});
diff --git a/packages/catalyst_builder/lib/src/builder/generator/service_provider/service_provider.dart b/packages/catalyst_builder/lib/src/builder/generator/service_provider/service_provider.dart
deleted file mode 100644
index 24388a7..0000000
--- a/packages/catalyst_builder/lib/src/builder/generator/service_provider/service_provider.dart
+++ /dev/null
@@ -1,48 +0,0 @@
-import 'package:code_builder/code_builder.dart' as cb;
-
-import '../../dto/dto.dart';
-import '../symbols.dart';
-import 'fields/fields.dart';
-import 'methods/methods.dart';
-
-/// Generates the code for the service provider.
-cb.Class buildServiceProviderClass(
- String providerClassName,
- String pluginClassName,
- List services,
-) {
- return cb.Class((c) => c
- ..name = providerClassName
- ..implements.addAll([
- serviceProviderT,
- serviceRegistryT,
- ])
- ..fields.addAll([
- parametersTemplate,
- bootedTemplate,
- knownServicesTemplate,
- exposeMapTemplate,
- serviceInstancesTemplate,
- servicesByTagTemplate,
- preloadedTypesTemplate,
- appliedPluginsTemplate,
- ])
- ..methods.addAll([
- tryResolveTemplate,
- tryResolveInternalTemplate,
- resolveTemplate,
- resolveByTagTemplate,
- tryResolveOrGetParameterTemplate,
- resolveOrGetParameterTemplate,
- bootTemplate(services),
- ensureBootedTemplate,
- hasTemplate,
- registerTemplate,
- registerInternalTemplate,
- enhanceTemplate(providerClassName),
- applyPlugin(),
- ])
- ..constructors.add(
- buildProviderConstructor(pluginClassName),
- ));
-}
diff --git a/packages/catalyst_builder/lib/src/builder/generator/symbols.dart b/packages/catalyst_builder/lib/src/builder/generator/symbols.dart
index 292bf56..f69f88f 100644
--- a/packages/catalyst_builder/lib/src/builder/generator/symbols.dart
+++ b/packages/catalyst_builder/lib/src/builder/generator/symbols.dart
@@ -13,98 +13,21 @@ final serviceDescriptorT = cb.refer('ServiceDescriptor', rootPackage);
/// [ServiceProvider]
final serviceProviderT = cb.refer('ServiceProvider', rootPackage);
-/// [ServiceRegistry]
-final serviceRegistryT = cb.refer('ServiceRegistry', rootPackage);
-
-/// [LazyServiceDescriptor]
-final lazyServiceDescriptorT = cb.refer('LazyServiceDescriptor', rootPackage);
-
-/// [ServiceNotFoundException]
-final serviceNotFoundExceptionT =
- cb.refer('ServiceNotFoundException', rootPackage);
-
-/// [DependencyNotFoundException]
-final dependencyNotFoundExceptionT =
- cb.refer('DependencyNotFoundException', rootPackage);
-
-/// [ServiceProvider.tryResolve]
-final tryResolve$ = cb.refer('tryResolve');
-
-final tryResolveInternal$ = cb.refer('_tryResolveInternal');
-
-/// [ServiceProvider.resolve]
-final resolve$ = cb.refer('resolve');
-
/// [ServiceProvider.resolveByTag]
final resolveByTag$ = cb.refer('resolveByTag');
-/// [ServiceProvider.has]
-final has$ = cb.refer('has');
-
-/// [ServiceRegistry.register]
-final register$ = cb.refer('register');
-
-final registerInternal$ = cb.refer('_registerInternal');
-
-/// [ServiceProvider.enhance]
-final enhance$ = cb.refer('enhance');
-
-/// this
-final this$ = cb.refer('this');
-
-/// _knownServices field in the service provider
-final knownServices$ = cb.refer('_knownServices');
-
-/// _exposeMap field in the service provider
-final exposeMap$ = cb.refer('_exposeMap');
-
-/// _serviceInstances field in the service provider
-final serviceInstances$ = cb.refer('_serviceInstances');
-
-/// _servicesByTag field in the service provider
-final servicesByTag$ = cb.refer('_servicesByTag');
-
-/// parameters field in the service provider
-final parameters$ = cb.refer('parameters');
-
/// tryResolveOrGetParameter method
final tryResolveOrGetParameter$ = cb.refer('tryResolveOrGetParameter');
/// resolveOrGetParameter method
final resolveOrGetParameter$ = cb.refer('resolveOrGetParameter');
-/// [ProviderNotBootedException]
-final providerNotBootedExceptionT =
- cb.refer('ProviderNotBootedException', rootPackage);
-
-/// [ProviderAlreadyBootedException]
-final providerAlreadyBootedExceptionT =
- cb.refer('ProviderAlreadyBootedException', rootPackage);
-
-/// _booted field in the service provider
-final booted$ = cb.refer('_booted');
-
-/// [ServiceProvider.boot] method
-final boot$ = cb.refer('boot');
-
-/// ensureBoot method
-final ensureBoot$ = cb.refer('_ensureBoot');
-
/// void type
final voidT = cb.refer('void');
/// Type type
final typeT = cb.refer('Type');
-/// Boolean type
-final boolT = cb.refer('bool');
-
-/// String type
-final stringT = cb.refer('String');
-
-/// dynamic type
-final dynamicT = cb.refer('dynamic');
-
/// Symbol type
final symbolT = cb.refer('Symbol');
@@ -119,12 +42,6 @@ cb.Reference mapOfT(cb.Reference tKey, cb.Reference tValue) =>
..types.addAll([tKey, tValue]))
.build();
-/// Make the reference nullable
-cb.Reference nullable(cb.Reference ref) => cb.refer("${ref.symbol}?", ref.url);
-
-/// _preloadedTypes field in the service provider
-final preloadedTypes$ = cb.refer('_preloadedTypes');
-
/// [ServiceProvider.applyPlugin] method
final applyPlugin$ = cb.refer('applyPlugin');
@@ -142,6 +59,3 @@ final providePreloadedTypes$ = cb.refer('providePreloadedTypes');
/// provideServiceTags method
final provideServiceTags$ = cb.refer('provideServiceTags');
-
-/// _appliedPlugins field
-final appliedPlugins$ = cb.refer('_appliedPlugins');
diff --git a/packages/catalyst_builder/lib/src/builder/service_provider_builder.dart b/packages/catalyst_builder/lib/src/builder/service_provider_builder.dart
deleted file mode 100644
index d0671ea..0000000
--- a/packages/catalyst_builder/lib/src/builder/service_provider_builder.dart
+++ /dev/null
@@ -1,103 +0,0 @@
-import 'dart:async';
-import 'dart:convert';
-
-import 'package:analyzer/dart/element/element.dart';
-import 'package:build/build.dart';
-import 'package:code_builder/code_builder.dart';
-import 'package:dart_style/dart_style.dart';
-import 'package:glob/glob.dart';
-
-import 'constants.dart';
-import 'dto/dto.dart';
-import 'generator/service_provider/service_provider.dart';
-import 'generator/service_provider/service_provider_plugin.dart';
-import 'helpers.dart';
-
-/// The ServiceProviderBuilder creates a service provider from the resulting
-/// preflight .json files.
-class ServiceProviderBuilder implements Builder {
- @override
- FutureOr build(BuildStep buildStep) async {
- if (!await buildStep.resolver.isLibrary(buildStep.inputId)) {
- return;
- }
- LibraryElement libraryElement;
- try {
- libraryElement = (await buildStep.inputLibrary);
- } catch (e) {
- log.warning('Error while processing input library. Skip for now.', e);
- return;
- }
-
- var annotation = libraryElement.topLevelElements
- .map((el) => el.metadata
- .where((m) => m.isLibraryAnnotation('GenerateServiceProvider')))
- .fold([], (prev, e) => [...prev, ...e]).firstOrNull;
-
- var isEntryPoint = annotation != null;
- if (!isEntryPoint) {
- return;
- }
-
- var constantValue = annotation.computeConstantValue()!;
- var providerClassName =
- constantValue.getField('providerClassName')!.toStringValue()!;
- var pluginClassName =
- constantValue.getField('pluginClassName')!.toStringValue()!;
-
- final entrypoint = Entrypoint(
- providerClassName: providerClassName,
- pluginClassName: pluginClassName,
- assetId: buildStep.inputId.uri,
- );
-
- var content = await _generateCode(buildStep, entrypoint);
- await buildStep.writeAsString(
- buildStep.inputId.changeExtension(serviceProviderExtension),
- content,
- );
- }
-
- Future _generateCode(
- BuildStep buildStep, Entrypoint entrypoint) async {
- final parts = [];
- final services = [];
-
- await for (final input
- in buildStep.findAssets(Glob('**/**$preflightExtension'))) {
- final jsonContent = await buildStep.readAsString(input);
- final part = PreflightPart.fromJson(
- jsonDecode(jsonContent) as Map,
- );
- parts.add(part);
- services.addAll(part.services);
- }
-
- final emitter = DartEmitter.scoped(
- orderDirectives: true,
- useNullSafetySyntax: true,
- );
-
- final rawOutput = Library(
- (l) => l.body.addAll([
- buildServiceProviderClass(
- entrypoint.providerClassName, entrypoint.pluginClassName, services),
- buildServiceProviderPluginClass(entrypoint.pluginClassName, services),
- ]),
- ).accept(emitter).toString();
-
- final content =
- DartFormatter(languageVersion: DartFormatter.latestLanguageVersion)
- .format('''
-// ignore_for_file: prefer_relative_imports, public_member_api_docs, implementation_imports
- $rawOutput
- ''');
- return content;
- }
-
- @override
- Map> get buildExtensions => {
- r'$lib$': [],
- r'.dart': [serviceProviderExtension],
- };
-}
diff --git a/packages/catalyst_builder/run_tests.sh b/packages/catalyst_builder/run_tests.sh
index 399fe8f..76642c6 100755
--- a/packages/catalyst_builder/run_tests.sh
+++ b/packages/catalyst_builder/run_tests.sh
@@ -3,9 +3,9 @@ set -e
cd ./example
dart run build_runner build --delete-conflicting-outputs
-cat "lib/example.catalyst_builder.g.dart" \
+cat "lib/example.catalyst_builder.plugin.g.dart" \
| sed -e "s+package\:catalyst_builder_example\/+./+g;" \
- | sed -e "s+package\:third_party_dependency\/+\.\.\/\.\.\/test\/third_party_dependency\/lib\/+g;w lib/example.catalyst_builder.g.dart"
+ | sed -e "s+package\:third_party_dependency\/+\.\.\/\.\.\/test\/third_party_dependency\/lib\/+g;w lib/example.catalyst_builder.plugin.g.dart"
cd ..
diff --git a/packages/catalyst_builder/test/integration/integration_test.dart b/packages/catalyst_builder/test/integration/integration_test.dart
deleted file mode 100644
index 68c9035..0000000
--- a/packages/catalyst_builder/test/integration/integration_test.dart
+++ /dev/null
@@ -1,274 +0,0 @@
-import 'package:catalyst_builder_contracts/catalyst_builder_contracts.dart';
-import 'package:test/test.dart';
-
-// ignore: avoid_relative_lib_imports
-import '../../example/lib/example.catalyst_builder.g.dart';
-
-// ignore: avoid_relative_lib_imports
-import '../../example/lib/public_api.dart'
- show
- Broadcaster,
- ChatProvider,
- CoolChatProvider,
- ManuallyWiredService,
- ManuallyWiredServiceImplementation,
- MySelfRegisteredService,
- MySingletonService,
- MyTransientService,
- PreloadService,
- SelfRegisteredService;
-
-// ignore: avoid_relative_lib_imports
-import '../third_party_dependency/lib/third_party_dependency.dart';
-
-void main() {
- late ServiceProvider serviceProvider;
-
- resetServiceProvider() {
- serviceProvider = ExampleProvider()..useThirdPartyPlugin();
- serviceProvider.parameters['sender_username'] = 'XYZ';
- }
-
- setUp(() {
- resetServiceProvider();
- serviceProvider.boot();
- });
-
- test('try/Resolve should throw when the provider is not booted', () {
- resetServiceProvider();
- expect(
- () => serviceProvider.resolve(),
- throwsA(const TypeMatcher()),
- );
- expect(
- () => serviceProvider.tryResolve(),
- throwsA(const TypeMatcher()),
- );
- });
-
- test('double boot should throw an exception', () {
- expect(
- () => serviceProvider.boot(),
- throwsA(const TypeMatcher()),
- );
- });
-
- test('tryResolve should not throw if a service was not found', () {
- var result = serviceProvider.tryResolve();
- expect(result, isNull);
- });
-
- test('resolve should throw if a service was not found', () {
- expect(
- () => serviceProvider.resolve(),
- throwsA(const TypeMatcher()),
- );
- });
-
- test('try/Resolve should inject parameters for non existing services', () {
- expect(serviceProvider.resolve().username, 'XYZ');
- expect(serviceProvider.tryResolve()?.username, 'XYZ');
- });
-
- test('Services can be exposed as a specific type', () {
- var provider = serviceProvider.resolve();
- expect(provider, const TypeMatcher());
- });
-
- test('PreLoaded services should be loaded on boot', () {
- expect(PreloadService.shouldPreload, isFalse);
- expect(PreloadService.wasPreloaded, isFalse);
- resetServiceProvider();
- PreloadService.shouldPreload = true;
- expect(PreloadService.wasPreloaded, isFalse);
- serviceProvider.boot();
- expect(PreloadService.wasPreloaded, isTrue);
- });
-
- test('Singleton Service Lifetime', () {
- var instance1 = serviceProvider.resolve();
- var instance2 = serviceProvider.resolve();
-
- expect(instance1, same(instance2));
- });
-
- test('Transient Service Lifetime', () {
- var instance1 = serviceProvider.resolve();
- var instance2 = serviceProvider.resolve();
-
- expect(instance1, isNot(same(instance2)));
- });
-
- test('Third party services', () {
- var svc = serviceProvider.resolve();
-
- expect(svc, const TypeMatcher());
- });
-
- test('Manually wired services', () {
- expect(ManuallyWiredServiceImplementation.shouldPreload, isFalse);
- expect(ManuallyWiredServiceImplementation.wasPreloaded, isFalse);
- resetServiceProvider();
- ManuallyWiredServiceImplementation.shouldPreload = true;
- expect(ManuallyWiredServiceImplementation.wasPreloaded, isFalse);
- serviceProvider.boot();
- expect(ManuallyWiredServiceImplementation.wasPreloaded, isTrue);
-
- var svc = serviceProvider.resolve();
- expect(svc, const TypeMatcher());
- });
-
- test('hasService', () {
- expect(serviceProvider.has(), isTrue);
- expect(serviceProvider.has(MySingletonService), isTrue);
- expect(serviceProvider.has(), isTrue);
- expect(serviceProvider.has(ChatProvider), isTrue);
- });
-
- test('service registration', () {
- if (serviceProvider is! ServiceRegistry) {
- fail('Service provider is not a ServiceRegistry');
- }
- expect(serviceProvider.has(), isFalse);
- (serviceProvider as ServiceRegistry).register(
- (provider) => MySelfRegisteredService(provider.resolve()),
- const Service(exposeAs: SelfRegisteredService),
- );
- expect(serviceProvider.has(), isTrue);
- });
-
- test('enhance', () {
- expect(serviceProvider.has(), isFalse);
-
- var newProvider = serviceProvider.enhance(services: [
- LazyServiceDescriptor(
- (p) => MySelfRegisteredService(p.resolve()),
- const Service(exposeAs: SelfRegisteredService),
- )
- ]);
-
- expect(newProvider.has(), isTrue);
- expect(serviceProvider.has(), isFalse);
-
- var mySvc = newProvider.resolve();
- expect(mySvc.foo, equals('bar'));
- });
-
- test('enhance with parameter', () {
- serviceProvider.parameters['foo'] = 'bar';
- serviceProvider.parameters['bar'] = 'baz';
- expect(serviceProvider.has(), isFalse);
-
- var newProvider = serviceProvider.enhance(
- parameters: {
- 'foo': 'overwritten',
- },
- services: [
- LazyServiceDescriptor(
- (p) => MySelfRegisteredService(
- p.resolve(), p.parameters['foo'] as String),
- const Service(exposeAs: SelfRegisteredService),
- ),
- ],
- );
-
- var mySvc = newProvider.resolve();
- expect(mySvc.foo, equals('overwritten'));
- expect(newProvider.parameters.containsKey('bar'), isTrue);
- });
-
- test('enhance with multiple descriptors', () {
- expect(serviceProvider.has(), isFalse);
- expect(serviceProvider.has(), isFalse);
-
- var newProvider = serviceProvider.enhance(
- services: [
- LazyServiceDescriptor(
- (p) => MySelfRegisteredService(p.resolve()),
- const Service(exposeAs: SelfRegisteredService),
- ),
- LazyServiceDescriptor(
- (p) => 'This should also work',
- const Service(exposeAs: String),
- ),
- ],
- );
-
- expect(newProvider.has(), isFalse);
- expect(newProvider.has(), isTrue);
- expect(newProvider.has(), isTrue);
- expect(newProvider.resolve(), isNotNull);
- expect(newProvider.resolve(), 'This should also work');
- });
-
- test('enhance should contain previous manual registered services', () {
- expect(serviceProvider.has(), isFalse);
- expect(serviceProvider.has(), isFalse);
-
- var newProvider = serviceProvider.enhance(
- services: [
- LazyServiceDescriptor(
- (p) => MySelfRegisteredService(p.resolve()),
- const Service(exposeAs: SelfRegisteredService),
- ),
- ],
- );
-
- expect(newProvider.has(), isTrue);
- expect(newProvider.has(), isFalse);
-
- var newProvider2 = newProvider.enhance(
- services: [
- LazyServiceDescriptor(
- (p) => 'This should also work',
- const Service(exposeAs: String),
- ),
- ],
- );
-
- expect(newProvider2.has(), isTrue);
- expect(newProvider2.has(), isTrue);
- });
-
- test('resolveByTag', () {
- var services = serviceProvider.resolveByTag(#chat);
- expect(services, isNotEmpty);
- });
-
- test('inject tagged services', () {
- var service = serviceProvider.resolve();
- expect(service.transports.length, equals(2));
- });
-
- test('enhance should not override default descriptors', () {
- expect(serviceProvider.has(), isTrue);
- expect(
- () => serviceProvider.resolve(),
- throwsA(const TypeMatcher()),
- );
-
- var enhanced = serviceProvider.enhance(
- services: [
- LazyServiceDescriptor(
- (p) => ServiceOnlyProvidedInEnhanced(),
- const Service(exposeAs: ServiceOnlyProvidedInEnhanced),
- )
- ],
- );
-
- expect(enhanced.has(), isTrue);
- expect(
- enhanced.resolve().dependency.foo,
- equals('bar'));
- });
-
- test('enhance should register singletons in the root provider', () {
- var enhanced1 = serviceProvider.enhance();
- expect(enhanced1.resolve().count,
- equals(1));
-
- var enhanced2 = serviceProvider.enhance();
- expect(enhanced2.resolve().count,
- equals(1));
- });
-}
diff --git a/packages/catalyst_builder_container/.gitignore b/packages/catalyst_builder_container/.gitignore
new file mode 100644
index 0000000..15dd5e6
--- /dev/null
+++ b/packages/catalyst_builder_container/.gitignore
@@ -0,0 +1,15 @@
+# Files and directories created by pub.
+.dart_tool/
+.packages
+.idea/
+
+# Conventional directory for build outputs.
+build/
+
+# Omit committing pubspec.lock for library packages; see
+# https://dart.dev/guides/libraries/private-files#pubspeclock.
+pubspec.lock
+**/**.preflight.json
+**/**.DS_Store
+
+**/*.g.dart
\ No newline at end of file
diff --git a/packages/catalyst_builder_container/CHANGELOG.md b/packages/catalyst_builder_container/CHANGELOG.md
new file mode 100644
index 0000000..a0edc74
--- /dev/null
+++ b/packages/catalyst_builder_container/CHANGELOG.md
@@ -0,0 +1,3 @@
+## 1.0.0-dev.1
+
+First pre-release
\ No newline at end of file
diff --git a/packages/catalyst_builder_container/LICENSE b/packages/catalyst_builder_container/LICENSE
new file mode 100644
index 0000000..e7a9b1d
--- /dev/null
+++ b/packages/catalyst_builder_container/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2025 Julian Finkler
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
\ No newline at end of file
diff --git a/packages/catalyst_builder_container/README.md b/packages/catalyst_builder_container/README.md
new file mode 100644
index 0000000..c9e350c
--- /dev/null
+++ b/packages/catalyst_builder_container/README.md
@@ -0,0 +1,12 @@
+[](https://github.com/mintware-de/catalyst_builder/blob/main/packages/catalyst_builder_container/LICENSE)
+[](https://pub.dartlang.org/packages/catalyst_builder_container)
+
+
+
+
+# Catalyst Builder Container
+
+This is the container package for [catalyst_builder](https://pub.dev/packages/catalyst_builder)
+
+For more details head over to the [wiki](https://github.com/mintware-de/catalyst_builder/wiki)
+
diff --git a/packages/catalyst_builder_container/analysis_options.yaml b/packages/catalyst_builder_container/analysis_options.yaml
new file mode 100644
index 0000000..1498fff
--- /dev/null
+++ b/packages/catalyst_builder_container/analysis_options.yaml
@@ -0,0 +1,6 @@
+include: package:lints/recommended.yaml
+
+analyzer:
+ language:
+ strict-casts: true
+ strict-inference: true
diff --git a/packages/catalyst_builder_container/example/.gitignore b/packages/catalyst_builder_container/example/.gitignore
new file mode 100644
index 0000000..b3bcdfa
--- /dev/null
+++ b/packages/catalyst_builder_container/example/.gitignore
@@ -0,0 +1,5 @@
+# https://dart.dev/guides/libraries/private-files
+# Created by `dart pub`
+.dart_tool/
+.cache/
+**/*.g.dart
diff --git a/packages/catalyst_builder_container/example/bin/example.dart b/packages/catalyst_builder_container/example/bin/example.dart
new file mode 100644
index 0000000..682fdc9
--- /dev/null
+++ b/packages/catalyst_builder_container/example/bin/example.dart
@@ -0,0 +1,18 @@
+import 'package:catalyst_builder_container/catalyst_builder_container.dart';
+import 'package:catalyst_builder_contracts/catalyst_builder_contracts.dart';
+import 'package:catalyst_builder_contracts_example/my_service.dart';
+
+import 'example.catalyst_builder.plugin.g.dart';
+
+@GenerateServiceProviderPlugin(
+ // Enter a name that is used for the service provider class
+ pluginClassName: 'ExampleProviderPlugin',
+)
+void main() {
+ final provider = ServiceContainer();
+ provider.useExampleProviderPlugin();
+ provider.boot();
+
+ final service = provider.resolve();
+ service.sayHello();
+}
diff --git a/packages/catalyst_builder_container/example/lib/my_service.dart b/packages/catalyst_builder_container/example/lib/my_service.dart
new file mode 100644
index 0000000..4b5ef21
--- /dev/null
+++ b/packages/catalyst_builder_container/example/lib/my_service.dart
@@ -0,0 +1,8 @@
+import 'package:catalyst_builder_contracts/catalyst_builder_contracts.dart';
+
+@Service()
+class MyService {
+ void sayHello() {
+ print('Hello World');
+ }
+}
diff --git a/packages/catalyst_builder_container/example/pubspec.yaml b/packages/catalyst_builder_container/example/pubspec.yaml
new file mode 100644
index 0000000..ed70cb2
--- /dev/null
+++ b/packages/catalyst_builder_container/example/pubspec.yaml
@@ -0,0 +1,25 @@
+name: catalyst_builder_contracts_example
+description: The example application for catalyst_builder_contracts
+version: 1.0.0
+
+publish_to: none
+
+environment:
+ sdk: ^3.6.1
+
+# Add regular dependencies here.
+dependencies:
+ catalyst_builder_contracts:
+ catalyst_builder_container:
+
+dev_dependencies:
+ build_runner:
+ catalyst_builder:
+
+dependency_overrides:
+ catalyst_builder_contracts:
+ path: ../../catalyst_builder_contracts
+ catalyst_builder:
+ path: ../../catalyst_builder
+ catalyst_builder_container:
+ path: ../
diff --git a/packages/catalyst_builder_container/lib/catalyst_builder_container.dart b/packages/catalyst_builder_container/lib/catalyst_builder_container.dart
new file mode 100644
index 0000000..11608a5
--- /dev/null
+++ b/packages/catalyst_builder_container/lib/catalyst_builder_container.dart
@@ -0,0 +1,3 @@
+library;
+
+export 'src/service_container.dart';
diff --git a/packages/catalyst_builder_container/lib/src/service_container.dart b/packages/catalyst_builder_container/lib/src/service_container.dart
new file mode 100644
index 0000000..05fd879
--- /dev/null
+++ b/packages/catalyst_builder_container/lib/src/service_container.dart
@@ -0,0 +1,189 @@
+import 'package:catalyst_builder_contracts/catalyst_builder_contracts.dart';
+
+/// This is a service container. Use it to register and resolve services
+/// from your app.
+class ServiceContainer implements ServiceProvider, ServiceRegistry {
+ @override
+ final parameters = {};
+
+ final _knownServices = {};
+
+ final _exposeMap = {};
+
+ final _servicesByTag = >{};
+
+ final _preloadedTypes = [];
+
+ final _appliedPlugins = [];
+
+ var _serviceInstances = {};
+
+ var _booted = false;
+
+ @override
+ T? tryResolve() {
+ return _tryResolveInternal(T);
+ }
+
+ T? _tryResolveInternal(Type t) {
+ _ensureBoot();
+ var exposedType = _exposeMap[t];
+ exposedType ??= t;
+ if (_serviceInstances.containsKey(exposedType)) {
+ return (_serviceInstances[exposedType] as T?);
+ }
+ var descriptor = _knownServices[exposedType];
+ if (descriptor == null) {
+ return null;
+ }
+ var instance = descriptor.produce();
+ if (descriptor.service.lifetime == ServiceLifetime.singleton) {
+ _serviceInstances[exposedType] = instance;
+ }
+ return (instance as T?);
+ }
+
+ @override
+ T resolve() {
+ _ensureBoot();
+ var resolved = tryResolve();
+ if (resolved != null) {
+ return resolved;
+ }
+ throw ServiceNotFoundException(T);
+ }
+
+ @override
+ List resolveByTag(Symbol tag) {
+ var services = [];
+ if (!_servicesByTag.containsKey(tag)) {
+ return services;
+ }
+ for (var svc in _servicesByTag[tag]!) {
+ services.add((_tryResolveInternal(svc) as dynamic));
+ }
+ return services;
+ }
+
+ @override
+ T? tryResolveOrGetParameter(String b) {
+ var resolvedService = tryResolve();
+ if (resolvedService != null) {
+ return resolvedService;
+ }
+ if (parameters[b] is T) {
+ return (parameters[b] as T);
+ }
+ return null;
+ }
+
+ @override
+ T resolveOrGetParameter(
+ Type requiredBy,
+ String param, [
+ String? parameter,
+ ]) {
+ var resolved = tryResolveOrGetParameter(parameter ?? param);
+ if (resolved == null) {
+ throw DependencyNotFoundException(
+ requiredBy,
+ param,
+ ServiceNotFoundException(T),
+ );
+ }
+ return resolved;
+ }
+
+ @override
+ void boot() {
+ if (_booted) {
+ throw const ProviderAlreadyBootedException();
+ }
+ _booted = true;
+ for (var type in _preloadedTypes) {
+ _tryResolveInternal(type);
+ }
+ }
+
+ void _ensureBoot() {
+ if (_booted == false) {
+ throw const ProviderNotBootedException();
+ }
+ }
+
+ @override
+ bool has([Type? type]) {
+ var lookupType = type ?? T;
+ return _knownServices.containsKey(_exposeMap[lookupType] ?? lookupType);
+ }
+
+ @override
+ void register(
+ ServiceFactory factory, [
+ Service service = const Service(),
+ ]) {
+ _registerInternal(T, factory, service);
+ }
+
+ void _registerInternal(
+ Type tReal,
+ ServiceFactory factory, [
+ Service service = const Service(),
+ ]) {
+ _knownServices[tReal] = ServiceDescriptor(service, () => factory(this));
+ if (service.exposeAs != null) {
+ _exposeMap[service.exposeAs!] = tReal;
+ }
+ }
+
+ @override
+ ServiceProvider enhance({
+ List services = const [],
+ Map parameters = const {},
+ }) {
+ _ensureBoot();
+ var enhanced = ServiceContainer();
+ _appliedPlugins.forEach(enhanced.applyPlugin);
+ enhanced._serviceInstances = _serviceInstances;
+ enhanced._knownServices.addAll(
+ Map.fromEntries(
+ _knownServices.entries.where(
+ (el) => !enhanced._knownServices.containsKey(el.key),
+ ),
+ ),
+ );
+ enhanced._exposeMap.addAll(_exposeMap);
+ for (var service in services) {
+ enhanced._registerInternal(
+ service.returnType,
+ service.factory,
+ service.service,
+ );
+ }
+ enhanced.parameters.addAll(this.parameters);
+ enhanced.parameters.addAll(parameters);
+ enhanced._booted = true;
+ return enhanced;
+ }
+
+ @override
+ void applyPlugin(ServiceProviderPlugin plugin) {
+ if (_booted) {
+ throw const ProviderAlreadyBootedException();
+ }
+ _appliedPlugins.add(plugin);
+ _knownServices.addAll(plugin.provideKnownServices(this));
+ _exposeMap.addAll(plugin.provideExposes());
+ _preloadedTypes.addAll(plugin.providePreloadedTypes());
+ for (var entry in plugin.provideServiceTags().entries) {
+ if (!_servicesByTag.containsKey(entry.key)) {
+ _servicesByTag[entry.key] = [];
+ }
+ for (var type in entry.value) {
+ if (!_servicesByTag[entry.key]!.contains(type)) {
+ _servicesByTag[entry.key]!.add(type);
+ }
+ }
+ }
+ }
+}
diff --git a/packages/catalyst_builder_container/pubspec.yaml b/packages/catalyst_builder_container/pubspec.yaml
new file mode 100644
index 0000000..5196b89
--- /dev/null
+++ b/packages/catalyst_builder_container/pubspec.yaml
@@ -0,0 +1,27 @@
+name: catalyst_builder_container
+description: A lightweight and easy to use dependency injection container for dart.
+version: 1.0.0-dev.1
+homepage: 'https://github.com/mintware-de/catalyst_builder'
+repository: 'https://github.com/mintware-de/catalyst_builder/tree/main/packages/catalyst_builder'
+documentation: 'https://github.com/mintware-de/catalyst_builder/wiki'
+issue_tracker: 'https://github.com/mintware-de/catalyst_builder/issues?q=is:open%20label:catalyst_builder_container'
+funding:
+ - https://github.com/sponsors/mintware-de
+
+topics:
+ - code-generation
+ - builder
+ - dependency-injection
+ - annotations
+ - service-provider
+
+environment:
+ sdk: ">=3.5.0 <4.0.0"
+
+dependencies:
+ analyzer: '>=6.2.0 <8.0.0'
+ catalyst_builder_contracts: ^2.0.0-dev.2
+
+dev_dependencies:
+ test: any
+ lints: any
\ No newline at end of file
diff --git a/packages/catalyst_builder_container/test/service_container_test.dart b/packages/catalyst_builder_container/test/service_container_test.dart
new file mode 100644
index 0000000..997eba3
--- /dev/null
+++ b/packages/catalyst_builder_container/test/service_container_test.dart
@@ -0,0 +1,366 @@
+import 'package:catalyst_builder_container/catalyst_builder_container.dart';
+import 'package:catalyst_builder_contracts/catalyst_builder_contracts.dart';
+import 'package:test/test.dart';
+
+void main() {
+ late ServiceProvider serviceProvider;
+
+ resetServiceProvider() {
+ serviceProvider = ServiceContainer();
+ serviceProvider.applyPlugin(_TestPlugin());
+ serviceProvider.parameters['paramOverride'] = 'XYZ';
+ }
+
+ setUp(() {
+ resetServiceProvider();
+ serviceProvider.boot();
+ });
+
+ test('try/Resolve should throw when the provider is not booted', () {
+ resetServiceProvider();
+ expect(
+ () => serviceProvider.resolve(),
+ throwsA(const TypeMatcher()),
+ );
+ });
+
+ test('double boot should throw an exception', () {
+ expect(
+ () => serviceProvider.boot(),
+ throwsA(const TypeMatcher()),
+ );
+ });
+
+ test('tryResolve should not throw if a service was not found', () {
+ var result = serviceProvider.tryResolve();
+ expect(result, isNull);
+ });
+
+ test('resolve should throw if a service was not found', () {
+ expect(
+ () => serviceProvider.resolve(),
+ throwsA(const TypeMatcher()),
+ );
+ });
+
+ test('try/Resolve should inject parameters for non existing services', () {
+ expect(serviceProvider.resolve<_ServiceThatRequiresParameter>().parameter,
+ 'XYZ');
+ expect(
+ serviceProvider.tryResolve<_ServiceThatRequiresParameter>()?.parameter,
+ 'XYZ');
+ });
+
+ test('Services can be exposed as a specific type', () {
+ var provider = serviceProvider.resolve<_MarkerInterface>();
+ expect(provider, const TypeMatcher<_ServiceThatRequiresParameter>());
+ });
+
+ test('PreLoaded services should be loaded on boot', () {
+ expect(_PreloadService.shouldPreload, isFalse);
+ expect(_PreloadService.wasPreloaded, isFalse);
+ resetServiceProvider();
+ _PreloadService.shouldPreload = true;
+ expect(_PreloadService.wasPreloaded, isFalse);
+ serviceProvider.boot();
+ expect(_PreloadService.wasPreloaded, isTrue);
+ });
+
+ test('Singleton Service Lifetime', () {
+ var instance1 = serviceProvider.resolve<_MySingleton>();
+ var instance2 = serviceProvider.resolve<_MySingleton>();
+
+ expect(instance1, same(instance2));
+ });
+
+ test('Transient Service Lifetime', () {
+ var instance1 = serviceProvider.resolve<_MyTransient>();
+ var instance2 = serviceProvider.resolve<_MyTransient>();
+
+ expect(instance1, isNot(same(instance2)));
+ });
+
+ test('hasService', () {
+ expect(serviceProvider.has<_MySingleton>(), isTrue);
+ expect(serviceProvider.has(), isFalse);
+ });
+
+ test('service registration', () {
+ if (serviceProvider is! ServiceRegistry) {
+ fail('Service provider is not a ServiceRegistry');
+ }
+ expect(serviceProvider.has<_SelfRegisteredService>(), isFalse);
+ (serviceProvider as ServiceRegistry).register(
+ (provider) => _MySelfRegisteredService(provider.resolve()),
+ const Service(exposeAs: _SelfRegisteredService),
+ );
+ expect(serviceProvider.has<_SelfRegisteredService>(), isTrue);
+ });
+
+ test('enhance', () {
+ expect(serviceProvider.has<_SelfRegisteredService>(), isFalse);
+
+ var newProvider = serviceProvider.enhance(services: [
+ LazyServiceDescriptor(
+ (p) => _MySelfRegisteredService(),
+ const Service(exposeAs: _SelfRegisteredService),
+ )
+ ]);
+
+ expect(newProvider.has<_SelfRegisteredService>(), isTrue);
+ expect(serviceProvider.has<_SelfRegisteredService>(), isFalse);
+
+ var mySvc = newProvider.resolve<_SelfRegisteredService>();
+ expect(mySvc.foo, equals('bar'));
+ });
+ test('enhance with parameter', () {
+ serviceProvider.parameters['foo'] = 'bar';
+ serviceProvider.parameters['bar'] = 'baz';
+ expect(serviceProvider.has<_SelfRegisteredService>(), isFalse);
+
+ var newProvider = serviceProvider.enhance(
+ parameters: {
+ 'foo': 'overwritten',
+ },
+ services: [
+ LazyServiceDescriptor(
+ (p) => _MySelfRegisteredService(p.parameters['foo'] as String),
+ const Service(exposeAs: _SelfRegisteredService),
+ ),
+ ],
+ );
+
+ var mySvc = newProvider.resolve<_SelfRegisteredService>();
+ expect(mySvc.foo, equals('overwritten'));
+ expect(newProvider.parameters.containsKey('bar'), isTrue);
+ });
+ test('enhance with multiple descriptors', () {
+ expect(serviceProvider.has<_SelfRegisteredService>(), isFalse);
+ expect(serviceProvider.has(), isFalse);
+
+ var newProvider = serviceProvider.enhance(
+ services: [
+ LazyServiceDescriptor<_MySelfRegisteredService>(
+ (p) => _MySelfRegisteredService(p.resolve()),
+ const Service(exposeAs: _SelfRegisteredService),
+ ),
+ LazyServiceDescriptor(
+ (p) => 'This should also work',
+ const Service(exposeAs: String),
+ ),
+ ],
+ );
+
+ expect(newProvider.has(), isFalse);
+ expect(newProvider.has<_SelfRegisteredService>(), isTrue);
+ expect(newProvider.has(), isTrue);
+ expect(newProvider.resolve<_SelfRegisteredService>(), isNotNull);
+ expect(newProvider.resolve(), 'This should also work');
+ });
+
+ test('enhance should contain previous manual registered services', () {
+ expect(serviceProvider.has<_SelfRegisteredService>(), isFalse);
+ expect(serviceProvider.has(), isFalse);
+
+ var newProvider = serviceProvider.enhance(
+ services: [
+ LazyServiceDescriptor<_MySelfRegisteredService>(
+ (p) => _MySelfRegisteredService(p.resolve()),
+ const Service(exposeAs: _SelfRegisteredService),
+ ),
+ ],
+ );
+
+ expect(newProvider.has<_SelfRegisteredService>(), isTrue);
+ expect(newProvider.has(), isFalse);
+
+ var newProvider2 = newProvider.enhance(
+ services: [
+ LazyServiceDescriptor(
+ (p) => 'This should also work',
+ const Service(exposeAs: String),
+ ),
+ ],
+ );
+
+ expect(newProvider2.has<_SelfRegisteredService>(), isTrue);
+ expect(newProvider2.has(), isTrue);
+ });
+
+ test('resolveByTag', () {
+ var services = serviceProvider.resolveByTag(#tagToInject);
+ expect(services, isNotEmpty);
+ });
+
+ test('inject tagged services', () {
+ var service = serviceProvider.resolve<_ServiceWithTaggedDependencies>();
+ expect(service.dependencies.length, equals(2));
+ });
+
+ test('enhance should not override default descriptors', () {
+ expect(serviceProvider.has<_ServiceThatDependOnEnhancedService>(), isTrue);
+ expect(
+ () => serviceProvider.resolve<_ServiceThatDependOnEnhancedService>(),
+ throwsA(const TypeMatcher()),
+ );
+
+ var enhanced = serviceProvider.enhance(
+ services: [
+ LazyServiceDescriptor<_ServiceOnlyProvidedInEnhanced>(
+ (p) => _ServiceOnlyProvidedInEnhanced(),
+ const Service(exposeAs: _ServiceOnlyProvidedInEnhanced),
+ )
+ ],
+ );
+
+ expect(enhanced.has<_ServiceThatDependOnEnhancedService>(), isTrue);
+ expect(
+ enhanced.resolve<_ServiceThatDependOnEnhancedService>().dependency.foo,
+ equals('bar'));
+ });
+
+ test('enhance should register singletons in the root provider', () {
+ var enhanced1 = serviceProvider.enhance();
+ expect(enhanced1.resolve<_SingletonThatShouldBeRegisteredInRoot>().count,
+ equals(1));
+
+ var enhanced2 = serviceProvider.enhance();
+ expect(enhanced2.resolve<_SingletonThatShouldBeRegisteredInRoot>().count,
+ equals(1));
+ });
+}
+
+// Testing services
+
+abstract interface class _MarkerInterface {
+ String get parameter;
+}
+
+class _ServiceThatRequiresParameter implements _MarkerInterface {
+ final String parameter;
+
+ _ServiceThatRequiresParameter(
+ @Inject(parameter: 'paramOverride') this.parameter);
+}
+
+class _MySingleton {}
+
+class _MyTransient {}
+
+class _SingletonThatShouldBeRegisteredInRoot {
+ static var _count = 0;
+
+ int get count => _count;
+
+ _SingletonThatShouldBeRegisteredInRoot() {
+ _count++;
+ }
+}
+
+class _ServiceOnlyProvidedInEnhanced {
+ String get foo => 'bar';
+}
+
+class _ServiceThatDependOnEnhancedService {
+ final _ServiceOnlyProvidedInEnhanced dependency;
+
+ _ServiceThatDependOnEnhancedService(this.dependency);
+}
+
+abstract class _SelfRegisteredService {
+ String get foo;
+
+ void sayHello();
+}
+
+class _MySelfRegisteredService implements _SelfRegisteredService {
+ @override
+ final String foo;
+
+ _MySelfRegisteredService([this.foo = 'bar']);
+
+ @override
+ void sayHello() {}
+}
+
+class _ServiceWithTaggedDependencies {
+ final List