Dependency injection with MediaWikiServices: accessing and creating services.
MediaWiki uses a service container and dependency injection (DI) pattern to manage shared objects. Rather than instantiating dependencies directly or relying on global singletons scattered through the codebase, services are registered centrally and injected where needed.
The heart of DI in MediaWiki is MediaWikiServices, which acts as the top-level factory (or registry) for services. It represents the tree of service objects that define MediaWiki’s application logic and serves as the entry point to all dependency injection for core.When MediaWikiServices::getInstance() is first called, it creates an instance and populates it with services defined in includes/ServiceWiring.php, as well as any additional wiring files listed in $wgServiceWiringFiles.
// Defined in includes/MediaWikiServices.phpnamespace MediaWiki;class MediaWikiServices extends ServiceContainer { // ... public static function getInstance(): self { ... }}
MediaWikiServices extends Wikimedia\Services\ServiceContainer. It has been available since MediaWiki 1.27.
MediaWikiServices::getInstance() should only be called in static entry points (such as static hook handlers or legacy functions). Application logic in service classes should receive services via constructor injection — never by calling getInstance() inside an instance method or accepting the MediaWikiServices object itself as a constructor parameter.
includes/ServiceWiring.php contains the default instantiator (factory) functions for all core services. It returns a PHP array where each key is a service name and each value is a static closure that receives the MediaWikiServices container and returns a new service instance.
// From includes/ServiceWiring.php'ActorStoreFactory' => static function ( MediaWikiServices $services ): ActorStoreFactory { return new ActorStoreFactory( new ServiceOptions( ActorStoreFactory::CONSTRUCTOR_OPTIONS, $services->getMainConfig() ), $services->getDBLoadBalancerFactory(), $services->getUserNameUtils(), $services->getTempUserConfig(), LoggerFactory::getInstance( 'ActorStore' ), $services->getHideUserUtils() );},'ArchivedRevisionLookup' => static function ( MediaWikiServices $services ): ArchivedRevisionLookup { return new ArchivedRevisionLookup( $services->getConnectionProvider(), $services->getRevisionStore() );},
Services must not vary their behavior on global state such as the current web request, RequestContext, or the current user. This ensures they are safe to use across web requests, APIs, jobs, and maintenance scripts.
Services receive configuration at instantiation time. Changes to global configuration variables after a service is created have no effect on it. To address this, Setup.php calls MediaWikiServices::resetGlobalInstance() once configuration and extension registration is complete.Services that manage their own singletons (unmanaged legacy services) must not hold references to services managed by MediaWikiServices, because after a reset those references become stale.