+ /**
+ * Add a service manipulator callback for the given service.
+ * This method may be used by extensions that need to wrap, replace, or re-configure a
+ * service. It would typically be called from a MediaWikiServices hook handler.
+ *
+ * The manipulator callback is called just after the service is instantiated.
+ * It can call methods on the service to change configuration, or wrap or otherwise
+ * replace it.
+ *
+ * @see defineService().
+ * @see redefineService().
+ *
+ * @note This will fail if the service was already instantiated.
+ *
+ * @since 1.32
+ *
+ * @param string $name The name of the service to manipulate.
+ * @param callable $manipulator Callback function that manipulates, wraps or replaces a
+ * service instance. The callback receives the new service instance and this the
+ * ServiceContainer as parameters, as well as any extra instantiation parameters specified
+ * when constructing this ServiceContainer. If the callback returns a value, that
+ * value replaces the original service instance.
+ *
+ * @throws NoSuchServiceException if $name is not a known service.
+ * @throws CannotReplaceActiveServiceException if the service was already instantiated.
+ */
+ public function addServiceManipulator( $name, callable $manipulator ) {
+ Assert::parameterType( 'string', $name, '$name' );
+
+ if ( !$this->hasService( $name ) ) {
+ throw new NoSuchServiceException( $name );
+ }
+
+ if ( isset( $this->services[$name] ) ) {
+ throw new CannotReplaceActiveServiceException( $name );
+ }
+
+ $this->serviceManipulators[$name][] = $manipulator;
+ }
+