# KeyedService and KeyedServiceFactory [KeyedService](https://source.chromium.org/chromium/chromium/src/+/main:components/keyed_service/core/keyed_service.h;l=24;drc=f5bdc89c7395ed24f1b8d196a3bdd6232d5bf771) and [KeyedServiceBaseFactory](https://source.chromium.org/chromium/chromium/src/+/main:components/keyed_service/core/keyed_service_base_factory.h;l=31;drc=447e4fe9632d6680991223b97b9c489f7edbf56f) are interfaces to support building a dependency tree of services corresponded to the same object such as [content::BrowserContext](https://source.chromium.org/chromium/chromium/src/+/main:content/public/browser/browser_context.h;l=107;drc=9f831c2a0f5f38a330fd237eb0ac7fa4d2845053). ## Overview When you would like to use keyed service design, inherit [KeyedService](https://source.chromium.org/chromium/chromium/src/+/main:components/keyed_service/core/keyed_service.h;l=24;drc=f5bdc89c7395ed24f1b8d196a3bdd6232d5bf771) to define the service class, and prepare KeyedServiceFactory for the instance ```cpp= class ArcIntentHelperBridge : public KeyedService ... { ...; void Shutdown() override; } class ArcIntentHelperBridgeFactory : public internal::ArcBrowserContextKeyedServiceFactoryBase< ArcIntentHelperBridge, ArcIntentHelperBridgeFactory> { static ArcIntentHelperBridgeFactory* GetInstance() {...} } ``` KeyedService design is often used to handle the initialization/shutdown process clearer, and also provide methods to get a singelton. KeyedService is mapped to some object like Profile and we can obtain the service using `profile` parameter from anywhere. ## KeyedService [KeyedService](https://source.chromium.org/chromium/chromium/src/+/main:components/keyed_service/core/keyed_service.h;l=24;drc=f5bdc89c7395ed24f1b8d196a3bdd6232d5bf771) interface supports two-phase destruction order. KeyedService are destroyed within two phases. First is to frop references and second is to actually delete object. First is done by `Shutdown` and second is done by the destructor. ```cpp= // First pass is shutdown. virtual void Shutdown() {} // Second pass is the actual deletion virtual ~KeyedService() = default; ``` Note that `Shutdown` is not an actual destructor, it's like OnDestroying() observer. `Shutdown` may not do anything if not required. In ArcIntentHelperBridge example, it calls OnArcIntentHelperBridgeShutdown observer which will remove its reference from the KeyedService. ```cpp= void ArcAsh::OnArcIntentHelperBridgeShutdown( arc::ArcIntentHelperBridge* bridge) { if (bridge) bridge->RemoveObserver(this); } ``` ## KeyedServiceFactory [BrowserContextKeyedServiceFactory](https://source.chromium.org/chromium/chromium/src/+/main:components/keyed_service/content/browser_context_keyed_service_factory.h;l=31;drc=371515598109bf869e1acbe5ea67813fc1a4cc3d) is a base class for KeyedServiceFactory which takes BrowserContext object to map a KeyedService. [GetServiceForBrowserContext](https://source.chromium.org/chromium/chromium/src/+/main:components/keyed_service/content/browser_context_keyed_service_factory.h;l=107;drc=371515598109bf869e1acbe5ea67813fc1a4cc3d) returns KeyedService paired with BrowserContext. KeyedServiceFactory is responsible for creating/getting KeyedService instance, and also resolving dependency. The latter responsibility is in [DependencyManager](https://source.chromium.org/chromium/chromium/src/+/main:components/keyed_service/core/dependency_manager.h;drc=85d0a1363092979464bf9ecbdfe03dba39bc8532) stored in KeyedServiceFactory as `dependency_manager_`. ## Note Gardening is very tough this week... zzz