neuroglia-python 0.6.21__tar.gz → 0.6.22__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (120) hide show
  1. {neuroglia_python-0.6.21 → neuroglia_python-0.6.22}/PKG-INFO +1 -1
  2. {neuroglia_python-0.6.21 → neuroglia_python-0.6.22}/pyproject.toml +1 -1
  3. {neuroglia_python-0.6.21 → neuroglia_python-0.6.22}/src/neuroglia/__init__.py +1 -1
  4. {neuroglia_python-0.6.21 → neuroglia_python-0.6.22}/src/neuroglia/hosting/configuration/data_access_layer.py +128 -5
  5. {neuroglia_python-0.6.21 → neuroglia_python-0.6.22}/LICENSE +0 -0
  6. {neuroglia_python-0.6.21 → neuroglia_python-0.6.22}/README.md +0 -0
  7. {neuroglia_python-0.6.21 → neuroglia_python-0.6.22}/src/neuroglia/application/__init__.py +0 -0
  8. {neuroglia_python-0.6.21 → neuroglia_python-0.6.22}/src/neuroglia/application/background_scheduler.py +0 -0
  9. {neuroglia_python-0.6.21 → neuroglia_python-0.6.22}/src/neuroglia/coordination/__init__.py +0 -0
  10. {neuroglia_python-0.6.21 → neuroglia_python-0.6.22}/src/neuroglia/coordination/abstractions.py +0 -0
  11. {neuroglia_python-0.6.21 → neuroglia_python-0.6.22}/src/neuroglia/coordination/leader_election.py +0 -0
  12. {neuroglia_python-0.6.21 → neuroglia_python-0.6.22}/src/neuroglia/coordination/redis_backend.py +0 -0
  13. {neuroglia_python-0.6.21 → neuroglia_python-0.6.22}/src/neuroglia/core/__init__.py +0 -0
  14. {neuroglia_python-0.6.21 → neuroglia_python-0.6.22}/src/neuroglia/core/module_loader.py +0 -0
  15. {neuroglia_python-0.6.21 → neuroglia_python-0.6.22}/src/neuroglia/core/operation_result.py +0 -0
  16. {neuroglia_python-0.6.21 → neuroglia_python-0.6.22}/src/neuroglia/core/problem_details.py +0 -0
  17. {neuroglia_python-0.6.21 → neuroglia_python-0.6.22}/src/neuroglia/core/type_extensions.py +0 -0
  18. {neuroglia_python-0.6.21 → neuroglia_python-0.6.22}/src/neuroglia/core/type_finder.py +0 -0
  19. {neuroglia_python-0.6.21 → neuroglia_python-0.6.22}/src/neuroglia/core/type_registry.py +0 -0
  20. {neuroglia_python-0.6.21 → neuroglia_python-0.6.22}/src/neuroglia/data/__init__.py +0 -0
  21. {neuroglia_python-0.6.21 → neuroglia_python-0.6.22}/src/neuroglia/data/abstractions.py +0 -0
  22. {neuroglia_python-0.6.21 → neuroglia_python-0.6.22}/src/neuroglia/data/exceptions.py +0 -0
  23. {neuroglia_python-0.6.21 → neuroglia_python-0.6.22}/src/neuroglia/data/infrastructure/__init__.py +0 -0
  24. {neuroglia_python-0.6.21 → neuroglia_python-0.6.22}/src/neuroglia/data/infrastructure/abstractions.py +0 -0
  25. {neuroglia_python-0.6.21 → neuroglia_python-0.6.22}/src/neuroglia/data/infrastructure/event_sourcing/__init__.py +0 -0
  26. {neuroglia_python-0.6.21 → neuroglia_python-0.6.22}/src/neuroglia/data/infrastructure/event_sourcing/abstractions.py +0 -0
  27. {neuroglia_python-0.6.21 → neuroglia_python-0.6.22}/src/neuroglia/data/infrastructure/event_sourcing/event_sourcing_repository.py +0 -0
  28. {neuroglia_python-0.6.21 → neuroglia_python-0.6.22}/src/neuroglia/data/infrastructure/event_sourcing/event_store/__init__.py +0 -0
  29. {neuroglia_python-0.6.21 → neuroglia_python-0.6.22}/src/neuroglia/data/infrastructure/event_sourcing/event_store/event_store.py +0 -0
  30. {neuroglia_python-0.6.21 → neuroglia_python-0.6.22}/src/neuroglia/data/infrastructure/event_sourcing/patches.py +0 -0
  31. {neuroglia_python-0.6.21 → neuroglia_python-0.6.22}/src/neuroglia/data/infrastructure/event_sourcing/read_model_reconciliator.py +0 -0
  32. {neuroglia_python-0.6.21 → neuroglia_python-0.6.22}/src/neuroglia/data/infrastructure/filesystem/__init__.py +0 -0
  33. {neuroglia_python-0.6.21 → neuroglia_python-0.6.22}/src/neuroglia/data/infrastructure/filesystem/filesystem_repository.py +0 -0
  34. {neuroglia_python-0.6.21 → neuroglia_python-0.6.22}/src/neuroglia/data/infrastructure/memory/__init__.py +0 -0
  35. {neuroglia_python-0.6.21 → neuroglia_python-0.6.22}/src/neuroglia/data/infrastructure/memory/memory_repository.py +0 -0
  36. {neuroglia_python-0.6.21 → neuroglia_python-0.6.22}/src/neuroglia/data/infrastructure/mongo/__init__.py +0 -0
  37. {neuroglia_python-0.6.21 → neuroglia_python-0.6.22}/src/neuroglia/data/infrastructure/mongo/enhanced_mongo_repository.py +0 -0
  38. {neuroglia_python-0.6.21 → neuroglia_python-0.6.22}/src/neuroglia/data/infrastructure/mongo/mongo_repository.py +0 -0
  39. {neuroglia_python-0.6.21 → neuroglia_python-0.6.22}/src/neuroglia/data/infrastructure/mongo/motor_repository.py +0 -0
  40. {neuroglia_python-0.6.21 → neuroglia_python-0.6.22}/src/neuroglia/data/infrastructure/mongo/serialization_helper.py +0 -0
  41. {neuroglia_python-0.6.21 → neuroglia_python-0.6.22}/src/neuroglia/data/infrastructure/mongo/typed_mongo_query.py +0 -0
  42. {neuroglia_python-0.6.21 → neuroglia_python-0.6.22}/src/neuroglia/data/infrastructure/resources/__init__.py +0 -0
  43. {neuroglia_python-0.6.21 → neuroglia_python-0.6.22}/src/neuroglia/data/infrastructure/resources/in_memory_storage_backend.py +0 -0
  44. {neuroglia_python-0.6.21 → neuroglia_python-0.6.22}/src/neuroglia/data/infrastructure/resources/postgres_resource_store.py +0 -0
  45. {neuroglia_python-0.6.21 → neuroglia_python-0.6.22}/src/neuroglia/data/infrastructure/resources/redis_resource_store.py +0 -0
  46. {neuroglia_python-0.6.21 → neuroglia_python-0.6.22}/src/neuroglia/data/infrastructure/resources/resource_repository.py +0 -0
  47. {neuroglia_python-0.6.21 → neuroglia_python-0.6.22}/src/neuroglia/data/infrastructure/tracing_mixin.py +0 -0
  48. {neuroglia_python-0.6.21 → neuroglia_python-0.6.22}/src/neuroglia/data/queries/generic/__init__.py +0 -0
  49. {neuroglia_python-0.6.21 → neuroglia_python-0.6.22}/src/neuroglia/data/queries/generic/get_by_id_query.py +0 -0
  50. {neuroglia_python-0.6.21 → neuroglia_python-0.6.22}/src/neuroglia/data/queries/generic/list_query.py +0 -0
  51. {neuroglia_python-0.6.21 → neuroglia_python-0.6.22}/src/neuroglia/data/queryable.py +0 -0
  52. {neuroglia_python-0.6.21 → neuroglia_python-0.6.22}/src/neuroglia/data/resources/__init__.py +0 -0
  53. {neuroglia_python-0.6.21 → neuroglia_python-0.6.22}/src/neuroglia/data/resources/abstractions.py +0 -0
  54. {neuroglia_python-0.6.21 → neuroglia_python-0.6.22}/src/neuroglia/data/resources/controller.py +0 -0
  55. {neuroglia_python-0.6.21 → neuroglia_python-0.6.22}/src/neuroglia/data/resources/serializers/__init__.py +0 -0
  56. {neuroglia_python-0.6.21 → neuroglia_python-0.6.22}/src/neuroglia/data/resources/serializers/xml_serializer.py +0 -0
  57. {neuroglia_python-0.6.21 → neuroglia_python-0.6.22}/src/neuroglia/data/resources/serializers/yaml_serializer.py +0 -0
  58. {neuroglia_python-0.6.21 → neuroglia_python-0.6.22}/src/neuroglia/data/resources/state_machine.py +0 -0
  59. {neuroglia_python-0.6.21 → neuroglia_python-0.6.22}/src/neuroglia/data/resources/watcher.py +0 -0
  60. {neuroglia_python-0.6.21 → neuroglia_python-0.6.22}/src/neuroglia/data/unit_of_work.py +0 -0
  61. {neuroglia_python-0.6.21 → neuroglia_python-0.6.22}/src/neuroglia/dependency_injection/__init__.py +0 -0
  62. {neuroglia_python-0.6.21 → neuroglia_python-0.6.22}/src/neuroglia/dependency_injection/service_provider.py +0 -0
  63. {neuroglia_python-0.6.21 → neuroglia_python-0.6.22}/src/neuroglia/dependency_injection/service_provider_backup.py +0 -0
  64. {neuroglia_python-0.6.21 → neuroglia_python-0.6.22}/src/neuroglia/eventing/__init__.py +0 -0
  65. {neuroglia_python-0.6.21 → neuroglia_python-0.6.22}/src/neuroglia/eventing/cloud_events/__init__.py +0 -0
  66. {neuroglia_python-0.6.21 → neuroglia_python-0.6.22}/src/neuroglia/eventing/cloud_events/cloud_event.py +0 -0
  67. {neuroglia_python-0.6.21 → neuroglia_python-0.6.22}/src/neuroglia/eventing/cloud_events/decorators.py +0 -0
  68. {neuroglia_python-0.6.21 → neuroglia_python-0.6.22}/src/neuroglia/eventing/cloud_events/infrastructure/__init__.py +0 -0
  69. {neuroglia_python-0.6.21 → neuroglia_python-0.6.22}/src/neuroglia/eventing/cloud_events/infrastructure/cloud_event_bus.py +0 -0
  70. {neuroglia_python-0.6.21 → neuroglia_python-0.6.22}/src/neuroglia/eventing/cloud_events/infrastructure/cloud_event_ingestor.py +0 -0
  71. {neuroglia_python-0.6.21 → neuroglia_python-0.6.22}/src/neuroglia/eventing/cloud_events/infrastructure/cloud_event_middleware.py +0 -0
  72. {neuroglia_python-0.6.21 → neuroglia_python-0.6.22}/src/neuroglia/eventing/cloud_events/infrastructure/cloud_event_publisher.py +0 -0
  73. {neuroglia_python-0.6.21 → neuroglia_python-0.6.22}/src/neuroglia/eventing/tracing.py +0 -0
  74. {neuroglia_python-0.6.21 → neuroglia_python-0.6.22}/src/neuroglia/expressions/__init__.py +0 -0
  75. {neuroglia_python-0.6.21 → neuroglia_python-0.6.22}/src/neuroglia/expressions/javascript_expression_translator.py +0 -0
  76. {neuroglia_python-0.6.21 → neuroglia_python-0.6.22}/src/neuroglia/extensions/cqrs_metrics_extensions.py +0 -0
  77. {neuroglia_python-0.6.21 → neuroglia_python-0.6.22}/src/neuroglia/extensions/mediator_extensions.py +0 -0
  78. {neuroglia_python-0.6.21 → neuroglia_python-0.6.22}/src/neuroglia/extensions/state_persistence_extensions.py +0 -0
  79. {neuroglia_python-0.6.21 → neuroglia_python-0.6.22}/src/neuroglia/hosting/__init__.py +0 -0
  80. {neuroglia_python-0.6.21 → neuroglia_python-0.6.22}/src/neuroglia/hosting/abstractions.py +0 -0
  81. {neuroglia_python-0.6.21 → neuroglia_python-0.6.22}/src/neuroglia/hosting/web.py +0 -0
  82. {neuroglia_python-0.6.21 → neuroglia_python-0.6.22}/src/neuroglia/integration/__init__.py +0 -0
  83. {neuroglia_python-0.6.21 → neuroglia_python-0.6.22}/src/neuroglia/integration/cache_repository.py +0 -0
  84. {neuroglia_python-0.6.21 → neuroglia_python-0.6.22}/src/neuroglia/integration/http_service_client.py +0 -0
  85. {neuroglia_python-0.6.21 → neuroglia_python-0.6.22}/src/neuroglia/integration/models.py +0 -0
  86. {neuroglia_python-0.6.21 → neuroglia_python-0.6.22}/src/neuroglia/logging/__init__.py +0 -0
  87. {neuroglia_python-0.6.21 → neuroglia_python-0.6.22}/src/neuroglia/logging/logger.py +0 -0
  88. {neuroglia_python-0.6.21 → neuroglia_python-0.6.22}/src/neuroglia/mapping/__init__.py +0 -0
  89. {neuroglia_python-0.6.21 → neuroglia_python-0.6.22}/src/neuroglia/mapping/mapper.py +0 -0
  90. {neuroglia_python-0.6.21 → neuroglia_python-0.6.22}/src/neuroglia/mediation/__init__.py +0 -0
  91. {neuroglia_python-0.6.21 → neuroglia_python-0.6.22}/src/neuroglia/mediation/behaviors/domain_event_cloudevent_behavior.py +0 -0
  92. {neuroglia_python-0.6.21 → neuroglia_python-0.6.22}/src/neuroglia/mediation/behaviors/domain_event_dispatching_middleware.py +0 -0
  93. {neuroglia_python-0.6.21 → neuroglia_python-0.6.22}/src/neuroglia/mediation/mediator.py +0 -0
  94. {neuroglia_python-0.6.21 → neuroglia_python-0.6.22}/src/neuroglia/mediation/metrics_middleware.py +0 -0
  95. {neuroglia_python-0.6.21 → neuroglia_python-0.6.22}/src/neuroglia/mediation/pipeline_behavior.py +0 -0
  96. {neuroglia_python-0.6.21 → neuroglia_python-0.6.22}/src/neuroglia/mediation/simple.py +0 -0
  97. {neuroglia_python-0.6.21 → neuroglia_python-0.6.22}/src/neuroglia/mediation/tracing_middleware.py +0 -0
  98. {neuroglia_python-0.6.21 → neuroglia_python-0.6.22}/src/neuroglia/mvc/__init__.py +0 -0
  99. {neuroglia_python-0.6.21 → neuroglia_python-0.6.22}/src/neuroglia/mvc/controller_base.py +0 -0
  100. {neuroglia_python-0.6.21 → neuroglia_python-0.6.22}/src/neuroglia/observability/__init__.py +0 -0
  101. {neuroglia_python-0.6.21 → neuroglia_python-0.6.22}/src/neuroglia/observability/framework.py +0 -0
  102. {neuroglia_python-0.6.21 → neuroglia_python-0.6.22}/src/neuroglia/observability/logging.py +0 -0
  103. {neuroglia_python-0.6.21 → neuroglia_python-0.6.22}/src/neuroglia/observability/metrics.py +0 -0
  104. {neuroglia_python-0.6.21 → neuroglia_python-0.6.22}/src/neuroglia/observability/otel_sdk.py +0 -0
  105. {neuroglia_python-0.6.21 → neuroglia_python-0.6.22}/src/neuroglia/observability/settings.py +0 -0
  106. {neuroglia_python-0.6.21 → neuroglia_python-0.6.22}/src/neuroglia/observability/tracing.py +0 -0
  107. {neuroglia_python-0.6.21 → neuroglia_python-0.6.22}/src/neuroglia/py.typed +0 -0
  108. {neuroglia_python-0.6.21 → neuroglia_python-0.6.22}/src/neuroglia/reactive/__init__.py +0 -0
  109. {neuroglia_python-0.6.21 → neuroglia_python-0.6.22}/src/neuroglia/reactive/rx_async.py +0 -0
  110. {neuroglia_python-0.6.21 → neuroglia_python-0.6.22}/src/neuroglia/serialization/__init__.py +0 -0
  111. {neuroglia_python-0.6.21 → neuroglia_python-0.6.22}/src/neuroglia/serialization/abstractions.py +0 -0
  112. {neuroglia_python-0.6.21 → neuroglia_python-0.6.22}/src/neuroglia/serialization/aggregate_serializer.py +0 -0
  113. {neuroglia_python-0.6.21 → neuroglia_python-0.6.22}/src/neuroglia/serialization/json.py +0 -0
  114. {neuroglia_python-0.6.21 → neuroglia_python-0.6.22}/src/neuroglia/utils/__init__.py +0 -0
  115. {neuroglia_python-0.6.21 → neuroglia_python-0.6.22}/src/neuroglia/utils/camel_model.py +0 -0
  116. {neuroglia_python-0.6.21 → neuroglia_python-0.6.22}/src/neuroglia/utils/case_conversion.py +0 -0
  117. {neuroglia_python-0.6.21 → neuroglia_python-0.6.22}/src/neuroglia/validation/__init__.py +0 -0
  118. {neuroglia_python-0.6.21 → neuroglia_python-0.6.22}/src/neuroglia/validation/business_rules.py +0 -0
  119. {neuroglia_python-0.6.21 → neuroglia_python-0.6.22}/src/neuroglia/validation/exceptions.py +0 -0
  120. {neuroglia_python-0.6.21 → neuroglia_python-0.6.22}/src/neuroglia/validation/validators.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: neuroglia-python
3
- Version: 0.6.21
3
+ Version: 0.6.22
4
4
  Summary: Port from .NET to Python of the Neuroglia Framework
5
5
  License: Apache
6
6
  License-File: LICENSE
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "neuroglia-python"
3
- version = "0.6.21"
3
+ version = "0.6.22"
4
4
  description = "Port from .NET to Python of the Neuroglia Framework"
5
5
  authors = ["Charles d'Avernas <charles.davernas@neuroglia.io>", "Bruno van de Werve <bvandewe@gmail.com>"]
6
6
  license = "Apache"
@@ -62,7 +62,7 @@ __all__ = [
62
62
  ]
63
63
 
64
64
  # Framework metadata
65
- __version__ = "0.6.18"
65
+ __version__ = "0.6.21"
66
66
  __author__ = "Neuroglia Team"
67
67
  __email__ = "team@neuroglia.io"
68
68
  __license__ = "Apache"
@@ -144,26 +144,149 @@ class DataAccessLayer:
144
144
  return builder
145
145
 
146
146
  class ReadModel:
147
- """Represents an helper class used to configure an application's Read Model DAL"""
147
+ """Represents a helper class used to configure an application's Read Model DAL
148
148
 
149
- @staticmethod
150
- def configure(builder: ApplicationBuilderBase, modules: list[str], repository_setup: Callable[[ApplicationBuilderBase, type, type], None]) -> ApplicationBuilderBase:
149
+ Supports two configuration patterns:
150
+ 1. Simplified: Pass database_name directly to constructor
151
+ 2. Custom: Pass custom repository_setup function to configure()
152
+
153
+ Examples:
154
+ # Simple configuration with database name
155
+ DataAccessLayer.ReadModel(database_name="myapp").configure(
156
+ builder, ["integration.models"]
157
+ )
158
+
159
+ # Custom factory (advanced, backwards compatible)
160
+ def custom_setup(builder_, entity_type, key_type):
161
+ # Custom configuration logic
162
+ pass
163
+ DataAccessLayer.ReadModel().configure(
164
+ builder, ["integration.models"], custom_setup
165
+ )
166
+ """
167
+
168
+ def __init__(self, database_name: Optional[str] = None):
169
+ """Initialize ReadModel configuration
170
+
171
+ Args:
172
+ database_name: Optional database name for MongoDB repositories.
173
+ If not provided, custom repository_setup must be used.
174
+ """
175
+ self._database_name = database_name
176
+
177
+ def configure(
178
+ self,
179
+ builder: ApplicationBuilderBase,
180
+ modules: list[str],
181
+ repository_setup: Optional[Callable[[ApplicationBuilderBase, type, type], None]] = None,
182
+ ) -> ApplicationBuilderBase:
151
183
  """Configures the application's Read Model DAL, scanning for types marked with the 'queryable' decorator within the specified modules
152
184
 
153
185
  Args:
154
186
  builder (ApplicationBuilderBase): the application builder to configure
155
187
  modules (List[str]): a list containing the names of the modules to scan for types decorated with 'queryable'
156
- repository_setup (Callable[[ApplicationBuilderBase, Type, Type], None]): a function used to setup the repository for the specified entity and key types
188
+ repository_setup (Optional[Callable[[ApplicationBuilderBase, Type, Type], None]]):
189
+ Optional custom function to setup repositories. If provided, takes precedence over database_name.
190
+ If not provided, uses simplified configuration with database_name.
191
+
192
+ Returns:
193
+ ApplicationBuilderBase: The configured builder
194
+
195
+ Raises:
196
+ ValueError: If consumer_group not specified in settings
197
+ ValueError: If neither repository_setup nor database_name is provided
157
198
  """
158
199
  consumer_group = builder.settings.consumer_group
159
200
  if not consumer_group:
160
201
  raise ValueError("Cannot configure Read Model DAL: consumer group not specified in application settings")
161
202
  builder.services.add_singleton(ReadModelConciliationOptions, singleton=ReadModelConciliationOptions(consumer_group))
162
203
  builder.services.add_singleton(HostedService, ReadModelReconciliator)
204
+
205
+ # If custom setup provided, use it (backwards compatible)
206
+ if repository_setup is not None:
207
+ for module in [ModuleLoader.load(module_name) for module_name in modules]:
208
+ for queryable_type in TypeFinder.get_types(module, lambda cls: inspect.isclass(cls) and hasattr(cls, "__queryable__")):
209
+ key_type = str # todo: reflect from DTO base type
210
+ repository_setup(builder, queryable_type, key_type)
211
+ builder.services.add_transient(RequestHandler, GetByIdQueryHandler[queryable_type, key_type]) # type: ignore
212
+ builder.services.add_transient(RequestHandler, ListQueryHandler[queryable_type, key_type]) # type: ignore
213
+ return builder
214
+
215
+ # Otherwise use simplified configuration with database_name
216
+ return self._configure_with_database_name(builder, modules)
217
+
218
+ def _configure_with_database_name(
219
+ self,
220
+ builder: ApplicationBuilderBase,
221
+ modules: list[str],
222
+ ) -> ApplicationBuilderBase:
223
+ """Configure repositories using simplified database_name pattern
224
+
225
+ Args:
226
+ builder: The application builder
227
+ modules: List of module names to scan for queryable types
228
+
229
+ Returns:
230
+ The configured builder
231
+
232
+ Raises:
233
+ ValueError: If database_name was not provided
234
+ """
235
+ if not self._database_name:
236
+ raise ValueError("Cannot configure Read Model with simplified API: " "database_name not provided. Either pass database_name to ReadModel() " "or use custom repository_setup function.")
237
+
238
+ from pymongo import MongoClient
239
+
240
+ from neuroglia.data.infrastructure.abstractions import (
241
+ QueryableRepository,
242
+ Repository,
243
+ )
244
+ from neuroglia.data.infrastructure.mongo.mongo_repository import (
245
+ MongoRepository,
246
+ MongoRepositoryOptions,
247
+ )
248
+ from neuroglia.dependency_injection import ServiceProvider
249
+
250
+ # Get MongoDB connection string
251
+ connection_string_name = "mongo"
252
+ connection_string = builder.settings.connection_strings.get(connection_string_name, None)
253
+ if connection_string is None:
254
+ raise ValueError(f"Missing '{connection_string_name}' connection string in application settings")
255
+
256
+ # Register MongoClient singleton (shared across all repositories)
257
+ builder.services.try_add_singleton(MongoClient, singleton=MongoClient(connection_string))
258
+
259
+ # Discover and configure each queryable type
163
260
  for module in [ModuleLoader.load(module_name) for module_name in modules]:
164
261
  for queryable_type in TypeFinder.get_types(module, lambda cls: inspect.isclass(cls) and hasattr(cls, "__queryable__")):
165
262
  key_type = str # todo: reflect from DTO base type
166
- repository_setup(builder, queryable_type, key_type)
263
+
264
+ # Register options for this entity type
265
+ builder.services.try_add_singleton(
266
+ MongoRepositoryOptions[queryable_type, key_type], # type: ignore
267
+ singleton=MongoRepositoryOptions[queryable_type, key_type](self._database_name), # type: ignore
268
+ )
269
+
270
+ # Register repository
271
+ builder.services.try_add_singleton(
272
+ Repository[queryable_type, key_type], # type: ignore
273
+ MongoRepository[queryable_type, key_type], # type: ignore
274
+ )
275
+
276
+ # Register queryable repository alias
277
+ def make_queryable_factory(qt, kt):
278
+ def queryable_factory(provider: ServiceProvider):
279
+ return provider.get_required_service(Repository[qt, kt]) # type: ignore
280
+
281
+ return queryable_factory
282
+
283
+ builder.services.try_add_singleton(
284
+ QueryableRepository[queryable_type, key_type], # type: ignore
285
+ implementation_factory=make_queryable_factory(queryable_type, key_type),
286
+ )
287
+
288
+ # Register query handlers
167
289
  builder.services.add_transient(RequestHandler, GetByIdQueryHandler[queryable_type, key_type]) # type: ignore
168
290
  builder.services.add_transient(RequestHandler, ListQueryHandler[queryable_type, key_type]) # type: ignore
291
+
169
292
  return builder