From e931a013fb756690400ffb0d35eae3e72ba54857 Mon Sep 17 00:00:00 2001 From: Julian Finkler Date: Sun, 13 Apr 2025 19:49:33 +0200 Subject: [PATCH 01/10] change: Removed the generated service provider With the new plugin system, the generated service provider itself does not contain more than a single line of code in the constructor. This makes the complexity and the advantages are out of proportion. --- packages/catalyst_builder/build.yaml | 9 - .../example/bin/catalyst_builder_example.dart | 5 +- .../catalyst_builder/example/lib/example.dart | 6 +- .../lib/src/builder/builders.dart | 5 - .../lib/src/builder/dto/dto.dart | 1 - .../lib/src/builder/dto/entrypoint.dart | 36 -- .../fields/applied_plugins.dart | 11 - .../service_provider/fields/booted.dart | 11 - .../service_provider/fields/expose_map.dart | 11 - .../service_provider/fields/fields.dart | 8 - .../fields/known_services.dart | 11 - .../service_provider/fields/parameters.dart | 12 - .../fields/preloaded_types.dart | 11 - .../fields/service_instances.dart | 10 - .../fields/services_by_tag.dart | 11 - .../methods/apply_plugin.dart | 71 ---- .../service_provider/methods/boot.dart | 29 -- .../service_provider/methods/constructor.dart | 11 - .../service_provider/methods/enhance.dart | 105 ----- .../methods/ensure_booted.dart | 16 - .../service_provider/methods/has.dart | 35 -- .../service_provider/methods/methods.dart | 14 - .../service_provider/methods/register.dart | 43 --- .../methods/register_internal.dart | 67 ---- .../service_provider/methods/resolve.dart | 23 -- .../methods/resolve_by_tag.dart | 35 -- .../methods/resolve_or_get_parameter.dart | 54 --- .../service_provider/methods/try_resolve.dart | 21 - .../methods/try_resolve_internal.dart | 50 --- .../methods/try_resolve_or_get_parameter.dart | 36 -- .../service_provider/service_provider.dart | 48 --- .../lib/src/builder/generator/symbols.dart | 86 ----- .../src/builder/service_provider_builder.dart | 103 ----- packages/catalyst_builder/run_tests.sh | 4 +- .../test/integration/integration_test.dart | 274 ------------- .../example/bin/example.dart | 9 +- .../example/pubspec.yaml | 7 +- .../lib/catalyst_builder_contracts.dart | 1 + .../lib/src/annotation/annotation.dart | 1 - .../annotation/generate_service_provider.dart | 20 - .../lib/src/default_service_provider.dart | 189 +++++++++ .../generate_service_provider_test.dart | 9 - .../unit/default_service_provider_test.dart | 365 ++++++++++++++++++ 43 files changed, 575 insertions(+), 1309 deletions(-) delete mode 100644 packages/catalyst_builder/lib/src/builder/dto/entrypoint.dart delete mode 100644 packages/catalyst_builder/lib/src/builder/generator/service_provider/fields/applied_plugins.dart delete mode 100644 packages/catalyst_builder/lib/src/builder/generator/service_provider/fields/booted.dart delete mode 100644 packages/catalyst_builder/lib/src/builder/generator/service_provider/fields/expose_map.dart delete mode 100644 packages/catalyst_builder/lib/src/builder/generator/service_provider/fields/fields.dart delete mode 100644 packages/catalyst_builder/lib/src/builder/generator/service_provider/fields/known_services.dart delete mode 100644 packages/catalyst_builder/lib/src/builder/generator/service_provider/fields/parameters.dart delete mode 100644 packages/catalyst_builder/lib/src/builder/generator/service_provider/fields/preloaded_types.dart delete mode 100644 packages/catalyst_builder/lib/src/builder/generator/service_provider/fields/service_instances.dart delete mode 100644 packages/catalyst_builder/lib/src/builder/generator/service_provider/fields/services_by_tag.dart delete mode 100644 packages/catalyst_builder/lib/src/builder/generator/service_provider/methods/apply_plugin.dart delete mode 100644 packages/catalyst_builder/lib/src/builder/generator/service_provider/methods/boot.dart delete mode 100644 packages/catalyst_builder/lib/src/builder/generator/service_provider/methods/constructor.dart delete mode 100644 packages/catalyst_builder/lib/src/builder/generator/service_provider/methods/enhance.dart delete mode 100644 packages/catalyst_builder/lib/src/builder/generator/service_provider/methods/ensure_booted.dart delete mode 100644 packages/catalyst_builder/lib/src/builder/generator/service_provider/methods/has.dart delete mode 100644 packages/catalyst_builder/lib/src/builder/generator/service_provider/methods/register.dart delete mode 100644 packages/catalyst_builder/lib/src/builder/generator/service_provider/methods/register_internal.dart delete mode 100644 packages/catalyst_builder/lib/src/builder/generator/service_provider/methods/resolve.dart delete mode 100644 packages/catalyst_builder/lib/src/builder/generator/service_provider/methods/resolve_by_tag.dart delete mode 100644 packages/catalyst_builder/lib/src/builder/generator/service_provider/methods/resolve_or_get_parameter.dart delete mode 100644 packages/catalyst_builder/lib/src/builder/generator/service_provider/methods/try_resolve.dart delete mode 100644 packages/catalyst_builder/lib/src/builder/generator/service_provider/methods/try_resolve_internal.dart delete mode 100644 packages/catalyst_builder/lib/src/builder/generator/service_provider/methods/try_resolve_or_get_parameter.dart delete mode 100644 packages/catalyst_builder/lib/src/builder/generator/service_provider/service_provider.dart delete mode 100644 packages/catalyst_builder/lib/src/builder/service_provider_builder.dart delete mode 100644 packages/catalyst_builder/test/integration/integration_test.dart delete mode 100644 packages/catalyst_builder_contracts/lib/src/annotation/generate_service_provider.dart create mode 100644 packages/catalyst_builder_contracts/lib/src/default_service_provider.dart delete mode 100644 packages/catalyst_builder_contracts/test/annotation/generate_service_provider_test.dart create mode 100644 packages/catalyst_builder_contracts/test/unit/default_service_provider_test.dart 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..3e272e8 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_contracts/catalyst_builder_contracts.dart'; import 'package:catalyst_builder_example/example.dart'; void main(List arguments) { - var provider = ExampleProvider(); + var provider = DefaultServiceProvider(); + 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/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_contracts/example/bin/example.dart b/packages/catalyst_builder_contracts/example/bin/example.dart index f4a7034..184a38e 100644 --- a/packages/catalyst_builder_contracts/example/bin/example.dart +++ b/packages/catalyst_builder_contracts/example/bin/example.dart @@ -1,14 +1,15 @@ import 'package:catalyst_builder_contracts/catalyst_builder_contracts.dart'; import 'package:catalyst_builder_contracts_example/my_service.dart'; -import 'example.catalyst_builder.g.dart'; +import 'example.catalyst_builder.plugin.g.dart'; -@GenerateServiceProvider( +@GenerateServiceProviderPlugin( // Enter a name that is used for the service provider class - providerClassName: 'ExampleProvider', + pluginClassName: 'ExampleProviderPlugin', ) void main() { - final provider = ExampleProvider(); + final provider = DefaultServiceProvider(); + provider.useExampleProviderPlugin(); provider.boot(); final service = provider.resolve(); diff --git a/packages/catalyst_builder_contracts/example/pubspec.yaml b/packages/catalyst_builder_contracts/example/pubspec.yaml index 4a39996..ee61a89 100644 --- a/packages/catalyst_builder_contracts/example/pubspec.yaml +++ b/packages/catalyst_builder_contracts/example/pubspec.yaml @@ -10,8 +10,13 @@ environment: # Add regular dependencies here. dependencies: catalyst_builder_contracts: - path: ../ dev_dependencies: build_runner: catalyst_builder: + +dependency_overrides: + catalyst_builder_contracts: + path: ../ + catalyst_builder: + path: ../../catalyst_builder diff --git a/packages/catalyst_builder_contracts/lib/catalyst_builder_contracts.dart b/packages/catalyst_builder_contracts/lib/catalyst_builder_contracts.dart index ef88c61..bcef8b6 100644 --- a/packages/catalyst_builder_contracts/lib/catalyst_builder_contracts.dart +++ b/packages/catalyst_builder_contracts/lib/catalyst_builder_contracts.dart @@ -5,4 +5,5 @@ export 'src/service_descriptor.dart'; export 'src/service_lifetime.dart'; export 'src/service_provider.dart'; export 'src/service_registry.dart'; +export 'src/default_service_provider.dart'; export 'src/service_provider_plugin.dart'; diff --git a/packages/catalyst_builder_contracts/lib/src/annotation/annotation.dart b/packages/catalyst_builder_contracts/lib/src/annotation/annotation.dart index 2d8fee2..a549387 100644 --- a/packages/catalyst_builder_contracts/lib/src/annotation/annotation.dart +++ b/packages/catalyst_builder_contracts/lib/src/annotation/annotation.dart @@ -1,4 +1,3 @@ -export 'generate_service_provider.dart'; export 'generate_service_provider_plugin.dart'; export 'inject.dart'; export 'preload.dart'; diff --git a/packages/catalyst_builder_contracts/lib/src/annotation/generate_service_provider.dart b/packages/catalyst_builder_contracts/lib/src/annotation/generate_service_provider.dart deleted file mode 100644 index 795b6f2..0000000 --- a/packages/catalyst_builder_contracts/lib/src/annotation/generate_service_provider.dart +++ /dev/null @@ -1,20 +0,0 @@ -/// Mark the file which contains this annotation as the entry point. -class GenerateServiceProvider { - /// Set this property for changing the class name of the generated - /// service provider. - final String providerClassName; - - /// Set this property for changing the class name of the generated - /// service provider plugin. - /// - /// If you're developing a third party plugin you need to set this property - /// otherwise the plugin class is not public since the default value is - /// prefixed by _; - final String pluginClassName; - - /// Mark this file as the entry point for the service container - const GenerateServiceProvider({ - this.providerClassName = 'DefaultServiceProvider', - String? pluginClassName, - }) : pluginClassName = pluginClassName ?? "_${providerClassName}Plugin"; -} diff --git a/packages/catalyst_builder_contracts/lib/src/default_service_provider.dart b/packages/catalyst_builder_contracts/lib/src/default_service_provider.dart new file mode 100644 index 0000000..f3b089c --- /dev/null +++ b/packages/catalyst_builder_contracts/lib/src/default_service_provider.dart @@ -0,0 +1,189 @@ +import 'package:catalyst_builder_contracts/catalyst_builder_contracts.dart'; + +class DefaultServiceProvider 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( + T Function(ServiceProvider) factory, [ + Service service = const Service(), + ]) { + _registerInternal(T, factory, service); + } + + void _registerInternal( + Type tReal, + T Function(ServiceProvider) 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 = DefaultServiceProvider(); + for (var plugin in _appliedPlugins) { + enhanced.applyPlugin(plugin); + } + 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_contracts/test/annotation/generate_service_provider_test.dart b/packages/catalyst_builder_contracts/test/annotation/generate_service_provider_test.dart deleted file mode 100644 index 9927dfb..0000000 --- a/packages/catalyst_builder_contracts/test/annotation/generate_service_provider_test.dart +++ /dev/null @@ -1,9 +0,0 @@ -import 'package:catalyst_builder_contracts/catalyst_builder_contracts.dart'; -import 'package:test/test.dart'; - -void main() { - test('exists', () { - var annotation = const GenerateServiceProvider(); - expect(annotation, const TypeMatcher()); - }); -} diff --git a/packages/catalyst_builder_contracts/test/unit/default_service_provider_test.dart b/packages/catalyst_builder_contracts/test/unit/default_service_provider_test.dart new file mode 100644 index 0000000..ab0ecbd --- /dev/null +++ b/packages/catalyst_builder_contracts/test/unit/default_service_provider_test.dart @@ -0,0 +1,365 @@ +import 'package:catalyst_builder_contracts/catalyst_builder_contracts.dart'; +import 'package:test/test.dart'; + +void main() { + late ServiceProvider serviceProvider; + + resetServiceProvider() { + serviceProvider = DefaultServiceProvider(); + 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 dependencies; + + _ServiceWithTaggedDependencies( + @Inject(tag: #tagToInject) List this.dependencies); +} + +class _PreloadService { + static bool shouldPreload = false; + static bool wasPreloaded = false; + + _PreloadService() { + if (shouldPreload) { + wasPreloaded = true; + } + } +} + +class _TestPlugin implements ServiceProviderPlugin { + @override + Map provideExposes() { + return {}; + } + + @override + Map provideKnownServices(ServiceProvider p) { + return { + _ServiceThatRequiresParameter: + ServiceDescriptor<_ServiceThatRequiresParameter>( + Service(), + () => _ServiceThatRequiresParameter(p.resolveOrGetParameter( + _ServiceThatRequiresParameter, 'parameter', 'paramOverride')), + ), + _MarkerInterface: ServiceDescriptor<_ServiceThatRequiresParameter>( + Service(exposeAs: _MarkerInterface), + () => _ServiceThatRequiresParameter(p.resolveOrGetParameter( + _ServiceThatRequiresParameter, 'parameter', 'paramOverride')), + ), + _MySingleton: ServiceDescriptor<_MySingleton>( + Service(lifetime: ServiceLifetime.singleton), + () => _MySingleton(), + ), + _MyTransient: ServiceDescriptor<_MyTransient>( + Service(lifetime: ServiceLifetime.transient), + () => _MyTransient(), + ), + _ServiceWithTaggedDependencies: + ServiceDescriptor<_ServiceWithTaggedDependencies>( + Service(lifetime: ServiceLifetime.singleton), + () => _ServiceWithTaggedDependencies( + p.resolveByTag(#tagToInject).cast())), + _SingletonThatShouldBeRegisteredInRoot: + ServiceDescriptor<_SingletonThatShouldBeRegisteredInRoot>( + Service(lifetime: ServiceLifetime.singleton), + () => _SingletonThatShouldBeRegisteredInRoot(), + ), + _ServiceThatDependOnEnhancedService: + ServiceDescriptor<_ServiceThatDependOnEnhancedService>( + Service(lifetime: ServiceLifetime.singleton), + () => _ServiceThatDependOnEnhancedService(p.resolveOrGetParameter( + _ServiceThatDependOnEnhancedService, 'dependency')), + ), + _PreloadService: ServiceDescriptor<_PreloadService>( + Service(), + () => _PreloadService(), + ) + }; + } + + @override + List providePreloadedTypes() { + return [_PreloadService]; + } + + @override + Map> provideServiceTags() { + return { + #tagToInject: [_MySingleton, _MyTransient], + }; + } +} From e1f3c76be0a5c32634629e56a02f2e639a1fcd46 Mon Sep 17 00:00:00 2001 From: Julian Finkler Date: Mon, 14 Apr 2025 04:51:17 +0200 Subject: [PATCH 02/10] change: Update readme --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 78b603a..f32ecbb 100644 --- a/README.md +++ b/README.md @@ -20,12 +20,12 @@ This is the workspace root, select a specific package for more details. |-----------------------------------------------------------------------|--------| | 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. | 🔲 | +| 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 | 🔲 | +| Remove the service provider subclasses | ☑️ | From aaa314de6cf0a3c442c9a9b92a2ced808fd67f09 Mon Sep 17 00:00:00 2001 From: Julian Finkler Date: Mon, 14 Apr 2025 05:11:29 +0200 Subject: [PATCH 03/10] feat: Add the catalyst_builder_container package --- README.md | 13 +++++---- .../catalyst_builder_container/.gitignore | 15 +++++++++++ .../catalyst_builder_container/CHANGELOG.md | 3 +++ packages/catalyst_builder_container/LICENSE | 21 +++++++++++++++ packages/catalyst_builder_container/README.md | 12 +++++++++ .../analysis_options.yaml | 6 +++++ .../example/.gitignore | 5 ++++ .../example/bin/example.dart | 18 +++++++++++++ .../example/lib/my_service.dart | 8 ++++++ .../example/pubspec.yaml | 25 +++++++++++++++++ .../lib/catalyst_builder_container.dart | 3 +++ .../lib/src/service_container.dart} | 10 +++---- .../catalyst_builder_container/pubspec.yaml | 27 +++++++++++++++++++ .../test/service_container_test.dart} | 3 ++- 14 files changed, 158 insertions(+), 11 deletions(-) create mode 100644 packages/catalyst_builder_container/.gitignore create mode 100644 packages/catalyst_builder_container/CHANGELOG.md create mode 100644 packages/catalyst_builder_container/LICENSE create mode 100644 packages/catalyst_builder_container/README.md create mode 100644 packages/catalyst_builder_container/analysis_options.yaml create mode 100644 packages/catalyst_builder_container/example/.gitignore create mode 100644 packages/catalyst_builder_container/example/bin/example.dart create mode 100644 packages/catalyst_builder_container/example/lib/my_service.dart create mode 100644 packages/catalyst_builder_container/example/pubspec.yaml create mode 100644 packages/catalyst_builder_container/lib/catalyst_builder_container.dart rename packages/{catalyst_builder_contracts/lib/src/default_service_provider.dart => catalyst_builder_container/lib/src/service_container.dart} (94%) create mode 100644 packages/catalyst_builder_container/pubspec.yaml rename packages/{catalyst_builder_contracts/test/unit/default_service_provider_test.dart => catalyst_builder_container/test/service_container_test.dart} (98%) diff --git a/README.md b/README.md index f32ecbb..2cb92ae 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,8 @@ 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. | [![Pub](https://img.shields.io/pub/v/catalyst_builder.svg)](https://pub.dartlang.org/packages/catalyst_builder)
![Pub Points](https://img.shields.io/pub/points/catalyst_builder)
![Pub Likes](https://img.shields.io/pub/likes/catalyst_builder)
![Pub Monthly Downloads](https://img.shields.io/pub/dm/catalyst_builder) | +| [`catalyst_builder`](./packages/catalyst_builder) | The builder package. Use this in your root package or plugin package to generate the ServiceContainerPlugin. | [![Pub](https://img.shields.io/pub/v/catalyst_builder.svg)](https://pub.dartlang.org/packages/catalyst_builder)
![Pub Points](https://img.shields.io/pub/points/catalyst_builder)
![Pub Likes](https://img.shields.io/pub/likes/catalyst_builder)
![Pub Monthly Downloads](https://img.shields.io/pub/dm/catalyst_builder) | +| [`catalyst_builder_container`](./packages/catalyst_builder_container) | The container package. Use this package to resolve services from the container. | [![Pub](https://img.shields.io/pub/v/catalyst_builder_container.svg)](https://pub.dartlang.org/packages/catalyst_builder_container)
![Pub Points](https://img.shields.io/pub/points/catalyst_builder_container)
![Pub Likes](https://img.shields.io/pub/likes/catalyst_builder_container)
![Pub Monthly Downloads](https://img.shields.io/pub/dm/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. | [![Pub](https://img.shields.io/pub/v/catalyst_builder_contracts.svg)](https://pub.dartlang.org/packages/catalyst_builder_contracts)
![Pub Points](https://img.shields.io/pub/points/catalyst_builder_contracts)
![Pub Likes](https://img.shields.io/pub/likes/catalyst_builder_contracts)
![Pub Monthly Downloads](https://img.shields.io/pub/dm/catalyst_builder_contracts) | ## Roadmap @@ -25,7 +26,9 @@ This is the workspace root, select a specific package for more details. # 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_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..50d5e64 --- /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..7b7e236 --- /dev/null +++ b/packages/catalyst_builder_container/README.md @@ -0,0 +1,12 @@ +[![GitHub license](https://img.shields.io/github/license/mintware-de/catalyst_builder.svg)](https://github.com/mintware-de/catalyst_builder/blob/main/packages/catalyst_builder_container/LICENSE) +[![Pub](https://img.shields.io/pub/v/catalyst_builder_container.svg)](https://pub.dartlang.org/packages/catalyst_builder_container) +![Pub Points](https://img.shields.io/pub/points/catalyst_builder_container) +![Pub Publisher](https://img.shields.io/pub/publisher/catalyst_builder_container) +![Pub Likes](https://img.shields.io/pub/likes/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_contracts/lib/src/default_service_provider.dart b/packages/catalyst_builder_container/lib/src/service_container.dart similarity index 94% rename from packages/catalyst_builder_contracts/lib/src/default_service_provider.dart rename to packages/catalyst_builder_container/lib/src/service_container.dart index f3b089c..0f24413 100644 --- a/packages/catalyst_builder_contracts/lib/src/default_service_provider.dart +++ b/packages/catalyst_builder_container/lib/src/service_container.dart @@ -1,6 +1,8 @@ import 'package:catalyst_builder_contracts/catalyst_builder_contracts.dart'; -class DefaultServiceProvider implements ServiceProvider, ServiceRegistry { +/// This is a service container. Use it to register and resolve services +/// from your app. +class ServiceContainer implements ServiceProvider, ServiceRegistry { @override final parameters = {}; @@ -140,10 +142,8 @@ class DefaultServiceProvider implements ServiceProvider, ServiceRegistry { Map parameters = const {}, }) { _ensureBoot(); - var enhanced = DefaultServiceProvider(); - for (var plugin in _appliedPlugins) { - enhanced.applyPlugin(plugin); - } + var enhanced = ServiceContainer(); + _appliedPlugins.forEach(enhanced.applyPlugin); enhanced._serviceInstances = _serviceInstances; enhanced._knownServices.addAll( Map.fromEntries( 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_contracts/test/unit/default_service_provider_test.dart b/packages/catalyst_builder_container/test/service_container_test.dart similarity index 98% rename from packages/catalyst_builder_contracts/test/unit/default_service_provider_test.dart rename to packages/catalyst_builder_container/test/service_container_test.dart index ab0ecbd..997eba3 100644 --- a/packages/catalyst_builder_contracts/test/unit/default_service_provider_test.dart +++ b/packages/catalyst_builder_container/test/service_container_test.dart @@ -1,3 +1,4 @@ +import 'package:catalyst_builder_container/catalyst_builder_container.dart'; import 'package:catalyst_builder_contracts/catalyst_builder_contracts.dart'; import 'package:test/test.dart'; @@ -5,7 +6,7 @@ void main() { late ServiceProvider serviceProvider; resetServiceProvider() { - serviceProvider = DefaultServiceProvider(); + serviceProvider = ServiceContainer(); serviceProvider.applyPlugin(_TestPlugin()); serviceProvider.parameters['paramOverride'] = 'XYZ'; } From 0271308a2953b7761b5c7d1ce328ee4b8f5df99d Mon Sep 17 00:00:00 2001 From: Julian Finkler Date: Mon, 14 Apr 2025 05:11:52 +0200 Subject: [PATCH 04/10] change: Use the catalyst_builder_container package in examples --- .../example/bin/catalyst_builder_example.dart | 4 ++-- packages/catalyst_builder/example/pubspec.yaml | 6 +++++- .../catalyst_builder_contracts/example/bin/example.dart | 3 ++- packages/catalyst_builder_contracts/example/pubspec.yaml | 2 ++ .../lib/catalyst_builder_contracts.dart | 1 - 5 files changed, 11 insertions(+), 5 deletions(-) diff --git a/packages/catalyst_builder/example/bin/catalyst_builder_example.dart b/packages/catalyst_builder/example/bin/catalyst_builder_example.dart index 3e272e8..a830c27 100644 --- a/packages/catalyst_builder/example/bin/catalyst_builder_example.dart +++ b/packages/catalyst_builder/example/bin/catalyst_builder_example.dart @@ -1,8 +1,8 @@ -import 'package:catalyst_builder_contracts/catalyst_builder_contracts.dart'; +import 'package:catalyst_builder_container/catalyst_builder_container.dart'; import 'package:catalyst_builder_example/example.dart'; void main(List arguments) { - var provider = DefaultServiceProvider(); + var provider = ServiceContainer(); provider.useExampleProviderPlugin(); provider.parameters['sender_username'] = 'Julian'; 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_contracts/example/bin/example.dart b/packages/catalyst_builder_contracts/example/bin/example.dart index 184a38e..682fdc9 100644 --- a/packages/catalyst_builder_contracts/example/bin/example.dart +++ b/packages/catalyst_builder_contracts/example/bin/example.dart @@ -1,3 +1,4 @@ +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'; @@ -8,7 +9,7 @@ import 'example.catalyst_builder.plugin.g.dart'; pluginClassName: 'ExampleProviderPlugin', ) void main() { - final provider = DefaultServiceProvider(); + final provider = ServiceContainer(); provider.useExampleProviderPlugin(); provider.boot(); diff --git a/packages/catalyst_builder_contracts/example/pubspec.yaml b/packages/catalyst_builder_contracts/example/pubspec.yaml index ee61a89..d67694f 100644 --- a/packages/catalyst_builder_contracts/example/pubspec.yaml +++ b/packages/catalyst_builder_contracts/example/pubspec.yaml @@ -20,3 +20,5 @@ dependency_overrides: path: ../ catalyst_builder: path: ../../catalyst_builder + catalyst_builder_container: + path: ../../catalyst_builder_container diff --git a/packages/catalyst_builder_contracts/lib/catalyst_builder_contracts.dart b/packages/catalyst_builder_contracts/lib/catalyst_builder_contracts.dart index bcef8b6..ef88c61 100644 --- a/packages/catalyst_builder_contracts/lib/catalyst_builder_contracts.dart +++ b/packages/catalyst_builder_contracts/lib/catalyst_builder_contracts.dart @@ -5,5 +5,4 @@ export 'src/service_descriptor.dart'; export 'src/service_lifetime.dart'; export 'src/service_provider.dart'; export 'src/service_registry.dart'; -export 'src/default_service_provider.dart'; export 'src/service_provider_plugin.dart'; From 5b3921530047d286a5ef956de51660d32e0fc929 Mon Sep 17 00:00:00 2001 From: Julian Finkler Date: Mon, 14 Apr 2025 05:12:29 +0200 Subject: [PATCH 05/10] feat: Add pipeline for catalyst_builder_container --- .github/workflows/dart.yml | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) 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 From 297017f34c81ec28f5c515117c1e144db9c64847 Mon Sep 17 00:00:00 2001 From: Julian Finkler Date: Mon, 14 Apr 2025 05:15:27 +0200 Subject: [PATCH 06/10] fix: Badges --- packages/catalyst_builder/README.md | 3 +-- packages/catalyst_builder_container/README.md | 2 +- packages/catalyst_builder_contracts/README.md | 2 +- 3 files changed, 3 insertions(+), 4 deletions(-) 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 @@ -[![GitHub license](https://img.shields.io/github/license/mintware-de/catalyst_builder.svg)](https://github.com/mintware-de/catalyst_builder/blob/main/packages/catalyst_builder/LICENSE) +[![GitHub license](https://img.shields.io/github/license/mintware-de/catalyst_builder)](https://github.com/mintware-de/catalyst_builder/blob/main/packages/catalyst_builder/LICENSE) ![GitHub issues](https://img.shields.io/github/issues/mintware-de/catalyst_builder) ![GitHub Workflow Status](https://img.shields.io/github/actions/workflow/status/mintware-de/catalyst_builder/dart.yml?branch=main) [![Pub](https://img.shields.io/pub/v/catalyst_builder.svg)](https://pub.dartlang.org/packages/catalyst_builder) ![Pub Points](https://img.shields.io/pub/points/catalyst_builder) ![Pub Publisher](https://img.shields.io/pub/publisher/catalyst_builder) -![Pub Popularity](https://img.shields.io/pub/popularity/catalyst_builder) ![Pub Likes](https://img.shields.io/pub/likes/catalyst_builder) # Catalyst Builder diff --git a/packages/catalyst_builder_container/README.md b/packages/catalyst_builder_container/README.md index 7b7e236..c9e350c 100644 --- a/packages/catalyst_builder_container/README.md +++ b/packages/catalyst_builder_container/README.md @@ -1,4 +1,4 @@ -[![GitHub license](https://img.shields.io/github/license/mintware-de/catalyst_builder.svg)](https://github.com/mintware-de/catalyst_builder/blob/main/packages/catalyst_builder_container/LICENSE) +[![GitHub license](https://img.shields.io/github/license/mintware-de/catalyst_builder)](https://github.com/mintware-de/catalyst_builder/blob/main/packages/catalyst_builder_container/LICENSE) [![Pub](https://img.shields.io/pub/v/catalyst_builder_container.svg)](https://pub.dartlang.org/packages/catalyst_builder_container) ![Pub Points](https://img.shields.io/pub/points/catalyst_builder_container) ![Pub Publisher](https://img.shields.io/pub/publisher/catalyst_builder_container) diff --git a/packages/catalyst_builder_contracts/README.md b/packages/catalyst_builder_contracts/README.md index 858790b..d3212ab 100644 --- a/packages/catalyst_builder_contracts/README.md +++ b/packages/catalyst_builder_contracts/README.md @@ -1,4 +1,4 @@ -[![GitHub license](https://img.shields.io/github/license/mintware-de/catalyst_builder.svg)](https://github.com/mintware-de/catalyst_builder/blob/main/packages/catalyst_builder_contracts/LICENSE) +[![GitHub license](https://img.shields.io/github/license/mintware-de/catalyst_builder)](https://github.com/mintware-de/catalyst_builder/blob/main/packages/catalyst_builder_contracts/LICENSE) [![Pub](https://img.shields.io/pub/v/catalyst_builder_contracts.svg)](https://pub.dartlang.org/packages/catalyst_builder_contracts) ![Pub Points](https://img.shields.io/pub/points/catalyst_builder_contracts) ![Pub Publisher](https://img.shields.io/pub/publisher/catalyst_builder_contracts) From 1c74f37df020fcbf187421ac4659eed6c3b73bc1 Mon Sep 17 00:00:00 2001 From: Julian Finkler Date: Mon, 14 Apr 2025 05:19:30 +0200 Subject: [PATCH 07/10] fix: Readme version --- packages/catalyst_builder_container/CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/catalyst_builder_container/CHANGELOG.md b/packages/catalyst_builder_container/CHANGELOG.md index 50d5e64..a0edc74 100644 --- a/packages/catalyst_builder_container/CHANGELOG.md +++ b/packages/catalyst_builder_container/CHANGELOG.md @@ -1,3 +1,3 @@ -## 1.0.0.dev-1 +## 1.0.0-dev.1 First pre-release \ No newline at end of file From 756e4a803af8660f599bd3a599fea23144b892c8 Mon Sep 17 00:00:00 2001 From: Julian Finkler Date: Mon, 14 Apr 2025 05:24:51 +0200 Subject: [PATCH 08/10] change: Add GenerateServiceProvider hint to changelog --- packages/catalyst_builder_contracts/CHANGELOG.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/packages/catalyst_builder_contracts/CHANGELOG.md b/packages/catalyst_builder_contracts/CHANGELOG.md index 5d12c05..c4c0290 100644 --- a/packages/catalyst_builder_contracts/CHANGELOG.md +++ b/packages/catalyst_builder_contracts/CHANGELOG.md @@ -1,3 +1,8 @@ +## Next + +### Breaking Changes +- Removed `GenerateServiceProvider`. Use `ServiceContainer` from the `catalyst_builder_container` package. + ## 2.0.0-dev.2 ### Breaking Changes From 46316f371a8f24079d634a20b69a0e75c02b6c89 Mon Sep 17 00:00:00 2001 From: Julian Finkler Date: Mon, 14 Apr 2025 13:00:57 +0200 Subject: [PATCH 09/10] change: Use the ServiceFactory type --- .../catalyst_builder_container/lib/src/service_container.dart | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/catalyst_builder_container/lib/src/service_container.dart b/packages/catalyst_builder_container/lib/src/service_container.dart index 0f24413..05fd879 100644 --- a/packages/catalyst_builder_container/lib/src/service_container.dart +++ b/packages/catalyst_builder_container/lib/src/service_container.dart @@ -119,7 +119,7 @@ class ServiceContainer implements ServiceProvider, ServiceRegistry { @override void register( - T Function(ServiceProvider) factory, [ + ServiceFactory factory, [ Service service = const Service(), ]) { _registerInternal(T, factory, service); @@ -127,7 +127,7 @@ class ServiceContainer implements ServiceProvider, ServiceRegistry { void _registerInternal( Type tReal, - T Function(ServiceProvider) factory, [ + ServiceFactory factory, [ Service service = const Service(), ]) { _knownServices[tReal] = ServiceDescriptor(service, () => factory(this)); From d155ed4ba1b934b587636d740f44e6e7ac7374b0 Mon Sep 17 00:00:00 2001 From: Julian Finkler Date: Mon, 14 Apr 2025 14:15:32 +0200 Subject: [PATCH 10/10] change: Update readme --- README.md | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index 2cb92ae..ad595ec 100644 --- a/README.md +++ b/README.md @@ -15,20 +15,11 @@ This is the workspace root, select a specific package for more details. ## Roadmap -# v4 (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) +# v5 (Current) | Description | Status | |---------------------------------------------------------------------------|--------| | Remove the annotations inside the catalyst_builder_package | ☑️ | | Remove the service provider subclasses | ☑️ | -| Stop generating the ServiceProvider and create a default ServiceContainer | 🔲 | +| Stop generating the ServiceProvider and create a default ServiceContainer | ☑️ | | Add scope support | 🔲 |