All notable changes to this project will be documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
- Updates package dependencies
- Updated package dependencies (as reported by Dependabot).
- Removed
hashicorp/go-version
dependency; added simple comparison functions to theversion.go
module instead.
- Updated package dependencies (as reported by Dependabot).
- Added new tests specifically for the service registration convenience functions.
- Added new tests for template functions and code generation.
- Adds documentation texts.
-
Adds the
SupportsRegisterActivatorFunc
, which is used in the registration functions instead ofServiceRegistry
. -
The convenience functions for registering services with different lifetimes are moved to the
register_functions.go
module, for better organization and separation of concerns. -
Multiple activator functions can be passed to the
RegisterTransient
,RegisterSingleton
, andRegisterScoped
convenience functions, allowing several services to be registered with a single method call.
- Several improvements and fixes related to handling interface and ellipsis parameters in reflection and code generation.
- Added the
validator.go
module to theregistration
package, introducing aValidator
service to verify service registrations:- Detects missing service dependencies.
- Identifies circular service registrations, where services depend on themselves.
- Added documentation comments to all exported types and methods.
Increased overall test coverage for the Parsley library and CLI utility from 55% to 80%, improving reliability and confidence in the codebase.
- Introduced new tests for almost all packages and modules
- Fixed issues discovered during testing, particularly in
ParsleyAggregateError
and thereflection
andgenerator
packages.
-
Refactored the (internal)
reflection
andgenerator
packages to enhance testability. Made minor internal adjustments to ensure better separation of concerns and improved testability. The updated type-model builder now supports pointer—and array-type parameters and result fields (the previous implementation could only handle scalar and simple array types). -
Introduced the
ParameterType
struct to store reflected parameter and field type information.
-
The
type_model_builder.go
module has been refactored to improve flexibility and maintain separation of concerns. By decoupling AST traversal from model building, the system now employs an extensible visitor pattern. -
The
generate mocks
command does now support additional annotations; use//parsley:mock
and//parsley:ignore
to gain full control over how mock generation is handled, while keeping the default behavior of including all interfaces. If//parsley:mock
is present, it takes precedence, meaning all interfaces are excluded by default, and only those explicitly marked with//parsley:mock
are included.
- Added a
version
command to display the current version of the Parsley CLI application. The command can also check for new versions by querying the latest release information from GitHub, notifying users if an update is available and providing instructions on how to update.
- Fixes matching of expected arguments in
mock_verify.go
- Adds the
FormatType
template function and fixes the type formatting for array types in default mock functions.
- Added improved testability for the
TemplateModelBuilder
by refactoring its constructor function to accept anAstFileAccessor
function instead of a filename. This allows for greater flexibility in testing, as the AST can now be sourced either from a file or directly from a string, making it easier to test different code inputs without relying on file I/O.
- Fixed an issue in the
type_model_builder.go
module where parameters and result fields of type array were not correctly handled. This update ensures that array types are properly represented in the generated template models, allowing for accurate code generation in cases involving arrays.
Starting with this release, the project's license has been changed from AGPLv3 to Apache License 2.0. The move to the Apache 2.0 license reflects my desire to make the library more accessible and easier to adopt, especially in commercial and proprietary projects.
- Adds the
generate mocks
CLI command that can generate configurable mock implemetations from interface types.
-
Several refactorings to the internal
generator
package with improvements to error handling and extensibility. -
Adds the
generic_generator.go
module, integrating generator templates, output file configuration, and template execution. The initial implementation resided in thegenerate_proxy_command.go
module. By pulling variables and control structures from parameters, the generator command logic could be moved to the (internal)generator
package, allowing the logic to be reused by other code-file generator commands. Adding other template-based generators based on (interface) type models can be achieved with less effort. -
Removes methods from the generator type model - uses a function map instead.
-
The generic code generator now formats generated code in canonical go fmt style.
- Fixes generator command short description texts
- Allows registration of (immutable) struct dependencies
- Minor changes to the bootstrap generator templates
Parsley is extended by the parsley-cli
utility application, which is the foundation for new library features that cannot be implemented on top of reflection. Support for proxy and/or decorator types is better integrated via a code generator approach.
-
Adds the
parsley-cli
application that adds code generation capabilities. -
The
init
command bootstraps a new Parsley application (amain.go
and anapplication.go
file providing the bare minimum to kick-start a dependency injection-enabled app). -
The
generate proxy
command generates extensible proxy types byMethodInterceptor
objects, which can function as proxies or decorator objects.
This version addresses issues with resolving and injecting services as lists.
- Adds the
RegisterList[T]
method to enable the resolver to inject lists of services. While resolving lists of a specific service type was already possible by theResolveRequiredServices[T]
method, the consumption of arrays in constructor functions requires an explicit registration. The list registration can be mixed with named service registrations.
-
Changes the key-type used to register and lookup service registrations (uses
ServiceKey
instead ofreflect.Type
). -
Adds
fmt.Stringer
implementations to registration types to improve the debugging experience. It also fixes the handling of types reflected from anonymous functions. -
Extracts some registry and resolver errors.
- Adds the
RegisterLazy[T]
method to register lazy service factories. Use the typeLazy[T]
to consume a lazy service dependency and call theValue() T
method on the lazy factory to request the actual service instance. The factory will create the service instance upon the first request, cache it, and return it for subsequent calls using theValue
method.
- Registers named services as transient services to resolve them also as a list of services (like services without a name). Changes the
createResolverRegistryAccessor
method so temporary registrations are selected first (and shadow permanent registrations). This behavior can also be leveraged inResolverOptionsFunc
to shadow other registrations when resolving instances viaResolveWithOptions.
-
Adds the
Activate[T]
method which can resolve an instance from an unregistered activator func. -
Allows registration and activation of pointer types (to not enforce usage of interfaces as abstractions).
-
Adds the
RegisterNamed[T]
method to register services of the same interface and allow to resolve them by name.
-
Renames the
ServiceType[T]
method toMakeServiceType[T]
; a service type represents now the reflected type and its name (which makes debugging and understanding service dependencies much easier). -
Replaces all usages of
reflect.Type
byServiceType
in all Parsley interfaces. -
Changes the
IsSame
method of theServiceRegistration
type; service registrations of type function are always treated as different service types.
- Fixes a bug in the
detectCircularDependency
function which could make the method get stuck in an infinite loop.
-
The service registry now accepts multiple registrations for the same interface (changes internal data structures to keep track of registrations; see
ServiceRegistrationList
). -
Adds the
ResolveRequiredServices[T]
convenience function to resolve all service instances;ResolveRequiredService[T]
can resolve a single service but will return an error if service registrations are ambiguous.
- Extends the resolver to handle multiple service registrations per interface type. The resolver returns resolved objects as a list.
- Support for factory functions to create instances of services based on input parameters provided at runtime
-
Reorganizes the whole package structure; adds sub-packages for
registration
andresolving
. A bunch of types that support the inner functionality of the package have been moved tointernal.
. -
Integration tests are moved to the
internal
package.
-
Service registrations can be bundled in a
ModuleFunc
to register related types as a unit. -
The service registry accepts object instances as singleton service registrations.
-
Adds the
ResolveRequiredService[T]
convenience function that resolves and safe-casts objects. -
Registers resolver instance with the registry so that the
Resolver
object can be injected into factory and constructor methods. -
The resolver can now accept instances of non-registered types via the
ResolveWithOptions[T]
method. -
ServiceRegistry
has new methods for creating linked and scoped registry objects (which share the sameServiceIdSequence
). Scoped registries inherit all parent service registrations, while linked registries are empty. SeeCreateLinkedRegistry
andCreateScope
methods.
-
A
ServiceRegistryAccessor
is no longer aServiceRegisty
, it is the other way around. -
The creation of service registrations and type activators has been refactored; see
activator.go
andservice_registration.go
modules. -
Multiple registries can be grouped with
NewMultiRegistryAccessor
to simplify the lookup of service registrations from linked registries. The resolver uses this accessor type to merge registered service types with object instances for unregistered types.
-
The resolver can now detect circular dependencies.
-
Adds helpers to register services with a certain lifetime scope.
- The registry rejects non-interface types.
-
Fixes error wrapping in custom error types.
-
Improves error handling for service registry and resolver.
-
Adds a service registry; the registry can map interfaces to implementation types via constructor functions.
-
Assign lifetime behaviour to services (singleton, scoped, or transient).
-
Adds a basic resolver (container) service.