Skip to main content
MediaWikiServices is the central dependency injection (DI) container for MediaWiki core, introduced in MediaWiki 1.27. It extends Wikimedia\Services\ServiceContainer and provides typed accessor methods for every registered service. Default service implementations are wired in includes/ServiceWiring.php.
Objects that need a service should receive it via constructor injection, not by calling MediaWikiServices::getInstance() directly inside a method. Use getInstance() only in static entry points (hooks registered via $wgHooks, maintenance scripts, etc.) where constructor injection is not possible.

Accessing the container

use MediaWiki\MediaWikiServices;

// Retrieve the global instance (static entry points only)
$services = MediaWikiServices::getInstance();

// Check whether the container has been initialised yet
if ( MediaWikiServices::hasInstance() ) {
    $revisionStore = MediaWikiServices::getInstance()->getRevisionStore();
}
Calling getInstance() before allowGlobalInstance() is called during bootstrap will throw a LogicException in PHPUnit tests and emit a deprecation warning in production. Never call it from service constructors or wiring files.
Services should declare their dependencies as constructor parameters so that the DI container can provide them automatically.
use MediaWiki\Page\PageStore;
use MediaWiki\Revision\RevisionStore;

class MyService {
    private PageStore $pageStore;
    private RevisionStore $revisionStore;

    public function __construct(
        PageStore $pageStore,
        RevisionStore $revisionStore
    ) {
        $this->pageStore = $pageStore;
        $this->revisionStore = $revisionStore;
    }
}
In ServiceWiring.php, wire the service by pulling its dependencies from the container:
'MyService' => static function ( MediaWikiServices $services ): MyService {
    return new MyService(
        $services->getPageStore(),
        $services->getRevisionStore()
    );
},

Service categories

AccessorReturn typeSince
getPageStore()PageStore1.36
getPageStoreFactory()PageStoreFactory1.36
getRevisionStore()RevisionStore1.31
getRevisionLookup()RevisionLookup1.31
getRevisionFactory()RevisionFactory1.31
getRevisionRenderer()RevisionRenderer1.32
getRevisionStoreFactory()RevisionStoreFactory1.32
getArchivedRevisionLookup()ArchivedRevisionLookup1.38
getWikiPageFactory()WikiPageFactory1.36
getPageUpdaterFactory()PageUpdaterFactory1.37
getPageProps()PageProps1.36
getRedirectLookup()RedirectLookup1.38
getRedirectStore()RedirectStore1.38
getDeletePageFactory()DeletePageFactory1.37
getMovePageFactory()MovePageFactory1.34
getMergeHistoryFactory()MergeHistoryFactory1.35
getRollbackPageFactory()RollbackPageFactory1.37
getUndeletePageFactory()UndeletePageFactory1.38
getParserOutputAccess()ParserOutputAccess1.36
AccessorReturn typeSince
getUserFactory()UserFactory1.35
getUserGroupManager()UserGroupManager1.35
getUserGroupManagerFactory()UserGroupManagerFactory1.35
getUserOptionsLookup()UserOptionsLookup1.35
getUserOptionsManager()UserOptionsManager1.35
getUserIdentityLookup()UserIdentityLookup1.36
getUserIdentityUtils()UserIdentityUtils1.41
getUserNameUtils()UserNameUtils1.35
getUserNamePrefixSearch()UserNamePrefixSearch1.36
getUserEditTracker()UserEditTracker1.35
getUserRegistrationLookup()UserRegistrationLookup1.41
getActorStore()ActorStore1.36
getActorStoreFactory()ActorStoreFactory1.36
getCentralIdLookup()CentralIdLookup1.37
getCentralIdLookupFactory()CentralIdLookupFactory1.37
getTempUserCreator()TempUserCreator1.39
getTempUserConfig()RealTempUserConfig1.39
AccessorReturn typeSinceNotes
getConnectionProvider()IConnectionProvider1.42Preferred over getDBLoadBalancer()
getDBLoadBalancer()ILoadBalancer1.28Main DB load balancer
getDBLoadBalancerFactory()LBFactory1.28Use getConnectionProvider() where possible
getDatabaseFactory()DatabaseFactory1.39
getBlobStore()BlobStore1.31
getBlobStoreFactory()BlobStoreFactory1.31
The preferred pattern for database access since MediaWiki 1.42 is IConnectionProvider:
use Wikimedia\Rdbms\IConnectionProvider;

class MyRepository {
    private IConnectionProvider $dbProvider;

    public function __construct( IConnectionProvider $dbProvider ) {
        $this->dbProvider = $dbProvider;
    }

    public function fetchRow( int $id ): ?array {
        $dbr = $this->dbProvider->getReplicaDatabase();
        return $dbr->newSelectQueryBuilder()
            ->select( [ 'page_id', 'page_title' ] )
            ->from( 'page' )
            ->where( [ 'page_id' => $id ] )
            ->fetchRow() ?: null;
    }
}
AccessorReturn typeSince
getContentHandlerFactory()IContentHandlerFactory1.35
getContentRenderer()ContentRenderer1.38
getContentTransformer()ContentTransformer1.37
getParserFactory()ParserFactory1.32
getParser()Parser1.29
getParserCache()ParserCache1.30
getParserCacheFactory()ParserCacheFactory1.36
getMagicWordFactory()MagicWordFactory1.32
getParsoidParserFactory()ParsoidParserFactory1.41
Do not call getParser() from within services or service wiring. Use getParserFactory()->create() to obtain a fresh Parser instance instead.
AccessorReturn typeSince
getAuthManager()AuthManager1.35
getBlockManager()BlockManager1.34
getPermissionManager()PermissionManager1.33
getGroupPermissionsLookup()GroupPermissionsLookup1.36
getRestrictionStore()RestrictionStore1.37
getRateLimiter()RateLimiter1.39
getBlockUserFactory()BlockUserFactory1.36
getUnblockUserFactory()UnblockUserFactory1.36
getDatabaseBlockStore()DatabaseBlockStore1.36
getPasswordFactory()PasswordFactory1.32
getPasswordReset()PasswordReset1.34
AccessorReturn typeSinceNotes
getMainWANObjectCache()WANObjectCache1.28Cross-datacenter WAN cache
getLocalServerObjectCache()BagOStuff1.28Per-server cache
getMainObjectStash()BagOStuff1.28Global stash
getObjectCacheFactory()ObjectCacheFactory1.42
getLinkCache()LinkCache1.28
getParserCache()ParserCache1.30
getLocalisationCache()LocalisationCache1.34
getMessageCache()MessageCache1.34
AccessorReturn typeSince
getSearchEngineFactory()SearchEngineFactory1.27
getSearchEngineConfig()SearchEngineConfig1.27
newSearchEngine()SearchEngine1.27
getTitleMatcher()TitleMatcher1.40
newSearchEngine() returns a new instance on every call because search engine objects maintain internal state.
AccessorReturn typeSince
getHttpRequestFactory()HttpRequestFactory1.31
getUrlUtils()UrlUtils1.39
getProxyLookup()ProxyLookup1.28
AccessorReturn typeSince
getHookContainer()HookContainer1.35
getTitleFormatter()TitleFormatter1.28
getTitleParser()TitleParser1.28
getTitleFactory()TitleFactory1.35
getLinkRenderer()LinkRenderer1.28
getLinkRendererFactory()LinkRendererFactory1.28
getJobQueueGroup()JobQueueGroup1.37
getJobQueueGroupFactory()JobQueueGroupFactory1.37
getJobFactory()JobFactory1.40
getJobRunner()JobRunner1.35
getLanguageFactory()LanguageFactory1.35
getLanguageConverterFactory()LanguageConverterFactory1.35
getLanguageNameUtils()LanguageNameUtils1.34
getNamespaceInfo()NamespaceInfo1.34
getConfigFactory()ConfigFactory1.27
getMainConfig()Config1.27
getObjectFactory()ObjectFactory1.34
getSpecialPageFactory()SpecialPageFactory1.32
getResourceLoader()ResourceLoader1.33
getSkinFactory()SkinFactory1.27
getInterwikiLookup()InterwikiLookup1.28
getWatchedItemStore()WatchedItemStoreInterface1.28
getWatchlistManager()WatchlistManager1.36
getCommentStore()CommentStore1.31
getCommentFormatter()CommentFormatter1.38
getGlobalIdGenerator()GlobalIdGenerator1.35
getStatsFactory()StatsFactory1.41

Service reset in tests

MediaWikiIntegrationTestCase resets the global container between test cases automatically. To override a specific service within a test, use overrideConfigValue() or setService():
use MediaWiki\MediaWikiServices;
use MediaWikiIntegrationTestCase;

class MyServiceTest extends MediaWikiIntegrationTestCase {

    public function testWithMockedRevisionStore(): void {
        $mockRevisionStore = $this->createMock( RevisionStore::class );
        $mockRevisionStore->method( 'getRevisionById' )->willReturn( null );

        // Replaces the service for the duration of this test
        $this->setService( 'RevisionStore', $mockRevisionStore );

        $revisionStore = MediaWikiServices::getInstance()->getRevisionStore();
        $this->assertNull( $revisionStore->getRevisionById( 99999 ) );
    }

    public function testResetSingleService(): void {
        // Low-level reset; use setService() above where possible
        MediaWikiServices::getInstance()
            ->resetServiceForTesting( 'LinkCache' );
    }
}
resetServiceForTesting() is guarded by MW_PHPUNIT_TEST and will throw outside of tests. For most cases, prefer setService() provided by MediaWikiIntegrationTestCase.

Resetting the global instance

resetGlobalInstance() creates a fresh container, optionally re-importing service wiring from the previous instance. The $mode parameter controls how expensive resources are handled:
// Discard expensive resources, reuse wiring (default)
MediaWikiServices::resetGlobalInstance();

// Allow expensive resources to be salvaged and reused
MediaWikiServices::resetGlobalInstance( null, 'quick' );

// Discard expensive resources and reload wiring files from disk
MediaWikiServices::resetGlobalInstance( null, 'reload' );
resetGlobalInstance() is only allowed during bootstrapping, installation, maintenance scripts, and PHPUnit tests. Calling it after MW_SERVICE_BOOTSTRAP_COMPLETE is defined in normal web requests will throw a LogicException.

Build docs developers (and LLMs) love