resolver-interop/interface

Interoperable autowiring resolver interfaces for PHP.

Maintainers

Package info

github.com/resolver-interop/interface

pkg:composer/resolver-interop/interface

Statistics

Installs: 8

Dependents: 0

Suggesters: 0

Stars: 0

Open Issues: 0

1.0.0-alpha1 2026-05-23 01:48 UTC

This package is not auto-updated.

Last update: 2026-05-24 15:07:19 UTC


README

Resolver-Interop provides an interoperable package of standard interfaces for autowiring resolver functionality. It reflects, refines, and reconciles the common practices identified within several pre-existing projects.

The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in BCP 14 (RFC 2119, RFC 8174).

Interfaces

This package defines the following interfaces:

ClassResolver

ClassResolver affords resolving a class to a new instance, and indicating whether a class may be resolved at all.

ClassResolver Methods

  • public function resolveClass(
        IocInterop\Interface\IocContainer $ioc,
        class-string<T> $class,
        mixed[] $arguments = [],
    ) : T;
    • Resolves the $class to return a new instance.

    • Directives:

      • Implementations MUST resolve the $class constructor parameters using logic identical to that specified by ReflectionParametersResolver.

      • Implementations MAY support property injection using logic identical to that specified by ReflectionPropertiesResolver.

      • Implementations MAY support method injection using logic identical to that specified by ReflectionMethodsResolver.

      • Implementations MAY support other forms of injection not specified herein.

      • Implementations MUST throw ResolverThrowable if the $class cannot be resolved.

  • public function mayResolveClass(string $class) : bool;
    • May the resolver attempt to resolve $class?

    • Notes:

      • The logic for this method is expressly unspecified. Implementations may check class_exists and ReflectionClass::isInstantiable(), or apply stricter rules; e.g., requiring a registered service-name alias, rejecting abstract bases that lack a concrete binding, or excluding PHP-internal classes. Consumers should treat a true result as "the implementation is willing to try resolveClass()", not as a guarantee that resolution will succeed.

ReflectionParametersResolver

ReflectionParametersResolver affords resolving an array of ReflectionParameter instances into an array of arguments.

ReflectionParametersResolver Methods

  • public function resolveParameters(
        IocInterop\Interface\IocContainer $ioc,
        ReflectionParameter[] $parameters,
        mixed[] $arguments = [],
    ) : mixed[];
    • Resolves the $parameters into the $arguments.

    • Directives:

    • Notes:

      • Mixed name and position keys for the same parameter in the $arguments pass through unchanged. Named and positional keys referring to the same parameters are preseved in the returned array as-is.

      • Extra and out-of-range keys in $arguments pass through unchanged. Keys that do not correspond to any parameter name or position, and positional keys whose integer index exceeds the parameter count, are preserved in the returned array as-is.

      • Resolved parameters are retained by name. Pre-filled positional arguments retain their integer keys; newly-resolved parameters are keyed on their parameter name, not their position.

      • Resolve all $arguments. Callers might pass one or more Resolvable as an argument; the implementation has to resolve them before returning.

ReflectionParameterResolver

ReflectionParameterResolver affords resolving a ReflectionParameter to an argument value.

This interface is also suitable for implementation on an Attribute to resolve a custom argument on a parameter.

  • Directives:

    • An Attribute implementing this interface MUST NOT be declared with Attribute::IS_REPEATABLE.

ReflectionParameterResolver Methods

  • public function resolveParameter(
        IocInterop\Interface\IocContainer $ioc,
        ReflectionParameter $parameter,
    ) : mixed;
    • Resolves the ReflectionParameter to an argument value.

    • Directives:

      • Implementations MUST resolve the $parameter in this order:

        • If the $parameter has one or more Attribute that implements ReflectionParameterResolver, implementations MUST resolve the $parameter using only the first such Attribute.

        • Otherwise, if the $parameter type is resolvable using logic identical to ReflectionTypeResolver and $ioc->hasService() returns true for that resolved type, implementations MUST resolve the $parameter to that service via $ioc->getService().

        • Otherwise, implementations MAY attempt to resolve the $parameter using implementation-specific logic; such logic is not defined herein.

        • Otherwise, if the $parameter has a default value, implementations MUST resolve the $parameter to that value.

      • Implementations MUST throw ResolverThrowable if the $parameter cannot be resolved.

    • Notes:

      • Variadic parameters resolve to a single value. Implementations resolve a variadic $parameter once (via attribute, type, or default) and return that value as the variadic argument. Spreading across multiple variadic slots is not specified by this interface.

ReflectionTypeResolver

ReflectionTypeResolver affords resolving a ReflectionType to a string name, or null if it cannot be resolved.

ReflectionTypeResolver Methods

  • public function resolveType(
        IocInterop\Interface\IocContainer $ioc,
        ?ReflectionType $type,
    ) : ?string;
    • Resolves a ReflectionType to a string name, or null if it cannot be resolved.

    • Directives:

      • If $type is null, implementations MUST return null.

      • Otherwise, if $type is a ReflectionNamedType, implementations MUST return the type name as produced by its getName() method.

      • Otherwise, the logic for determining the return type name is implementation-defined.

    • Notes:

      • Compound and other type handling is left to the implementation. For example, ReflectionUnionType and ReflectionIntersectionType handling may vary between implementations: one might iterate the branches and return the first whose name corresponds to an $ioc service name; another might return the compound stringification (e.g. "Foo|Bar") and let the container lookup handle it; yet another might return null out of hand.

ReflectionMethodsResolver

ReflectionMethodsResolver affords instantiating and invoking ReflectionMethodResolver attributes on object methods.

ReflectionMethodsResolver Methods

  • public function resolveMethods(
        IocInterop\Interface\IocContainer $ioc,
        ReflectionMethod[] $methods,
        object $object,
    ) : void;

ReflectionMethodResolver

ReflectionMethodResolver affords method injection when implemented on a method-targeted Attribute.

  • Directives:

    • An Attribute implementing this interface MUST NOT be declared with Attribute::IS_REPEATABLE.

ReflectionMethodResolver Methods

  • public function resolveMethod(
        IocInterop\Interface\IocContainer $ioc,
        ReflectionMethod $method,
        object $object,
    ) : void;
    • Invokes the ReflectionMethod on the $object.

    • Directives:

      • Implementations MUST support parameter injection using logic identical to that specified by ReflectionParametersResolver.

      • Implementations MUST invoke $method on $object with the resolved arguments.

      • Implementations MUST throw ResolverThrowable if resolution fails.

ReflectionPropertiesResolver

ReflectionPropertiesResolver affords instantiating and invoking ReflectionPropertyResolver attributes on object properties.

ReflectionPropertiesResolver Methods

  • public function resolveProperties(
        IocInterop\Interface\IocContainer $ioc,
        ReflectionProperty[] $properties,
        object $object,
    ) : void;
    • Resolves the attributed $properties on the $object.

    • Directives:

ReflectionPropertyResolver

ReflectionPropertyResolver affords property injection when implemented on a property-targeted Attribute.

  • Directives:

    • An Attribute implementing this interface MUST NOT be declared with Attribute::IS_REPEATABLE.

ReflectionPropertyResolver Methods

  • public function resolveProperty(
        IocInterop\Interface\IocContainer $ioc,
        ReflectionProperty $property,
        object $object,
    ) : void;
    • Sets the ReflectionProperty on an object.

    • Directives:

      • Implementations MUST resolve the $property in this order:

        • Implementations MAY attempt to resolve the $property using implementation-specific logic; such logic is not defined herein.

        • Otherwise, implementations MUST resolve the $property to the IocContainer service whose name matches the property type as produced by ReflectionTypeResolver, via $ioc->getService().

      • Implementations MUST throw ResolverThrowable if resolution of $property is attempted and fails.

CallResolver

CallResolver affords resolving a callable's parameters and invoking it, returning the call's result.

CallResolver Methods

  • public function resolveCall(
        IocInterop\Interface\IocContainer $ioc,
        callable $callable,
        mixed[] $arguments = [],
    ) : mixed;
    • Resolves the $callable to return its result.

    • Directives:

      • Implementations MUST resolve the $callable's parameters using logic identical to that specified by ReflectionParametersResolver's resolveParameters(), including the $arguments pre-fill and Resolvable-unwrap semantics specified there.

      • Implementations MUST invoke the $callable with the resolved $arguments and MUST return the result of that invocation.

      • Implementations MUST throw ResolverThrowable if the $callable cannot be resolved.

Resolvable

Resolvable affords an implementing object the ability to resolve itself to a value.

  • Notes:

    • Resolvable defers container calls until the moment of resolution. Wrapping a container call in a Resolvable lets the implmenting object be pass around without forcing the container interation at construction time.

Resolvable Methods

  • public function resolve(IocInterop\Interface\IocContainer $ioc) : mixed;
    • Resolves the implementing object to a value.

    • Directives:

      • Implementations MUST return a value that is neither itself a Resolvable nor contains any Resolvable instances.

      • Implementations MUST throw ResolverThrowable if the object cannot be resolved.

    • Notes:

      • Resolve recursively as needed. Some implementations may return arrays or objects; the implementation might need to check their contents for other Resolvable instances so that the return value is fully and deeply resolved.

ResolverThrowable

ResolverThrowable extends Throwable to mark an Exception as resolver-related.

It adds no class members.

Implementations

Q & A

Why are there so many interfaces?

The researched projects typically afford autowiring through a single container class with several methods (get(), make(), call(), and so on), each performing a distinct resolution task.

Resolver-Interop opts to split those operations into separate interfaces. Doing so allows consumers to depend only on the specific methods they need, and implementors to combine them as they see fit.

Why are setter-injection and property-injection supported?

Constructor injection is the documented default across all the researched projects. Setter-injection is generally supported, whereas property-injection is far less common.

Resolver-Interop summarizes this guidance evident from the projects:

  • constructor injection is preferred above all;

  • but sometimes setter-injection is unavoidable, especially in legacy or refactoring scenarios;

  • and while property-injection is to be shunned prejudicially, having it available as an absolute last resort can be useful.

Thus, while Resolver-Interop does not forbid post-construction injection, it attempts to make explicit the appropriate scope for these alternative forms of injection.