3.3.4. Module Container
In this chapter, you'll learn about the module container and how to resolve resources from it.
Since modules are isolated, each module has a local container used only by the resources of that module.
So, resources in the module, such as services or loaders, can only resolve other resources registered in the module's container, and some Framework tools that the Medusa application registers in the module's container.
List of Registered Resources#
Find a list of resources or dependencies registered in a module's container in the Container Resources reference.
Resolve Resources from the Module Container#
Resolve in Services#
A service's constructor accepts as a first parameter an object used to resolve resources registered in the module's container. To resolve a resource, add the resource's registration name as a property of the object.
For example, to resolve the Logger from the container:
1import { Logger } from "@medusajs/framework/types"2 3type InjectedDependencies = {4 logger: Logger5}6 7export default class BlogModuleService {8 protected logger_: Logger9 10 constructor({ logger }: InjectedDependencies) {11 this.logger_ = logger12 13 this.logger_.info("[BlogModuleService]: Hello World!")14 }15 16 // ...17}
You can then use the logger in the service's methods.
Resolve in Loaders#
Loaders accept an object parameter with the property container
. Its value is the module's container that can be used to resolve resources using its resolve
method.
For example, to resolve the Logger in a loader:
1import {2 LoaderOptions,3} from "@medusajs/framework/types"4import { 5 ContainerRegistrationKeys,6} from "@medusajs/framework/utils"7 8export default async function helloWorldLoader({9 container,10}: LoaderOptions) {11 const logger = container.resolve(ContainerRegistrationKeys.LOGGER)12 13 logger.info("[helloWorldLoader]: Hello, World!")14}
You can then use the logger in the loader's code.
Caveat: Resolving Module Services in Loaders#
Consider a module that has a main service BrandModuleService
, and an internal service CmsService
. Medusa will register both of these services in the module's container.
However, loaders are executed before any services are initialized and registered in the module's container. So, you can't resolve the BrandModuleService
and CmsService
in a loader.
Instead, if your main service extends the MedusaService
service factory, you can resolve the internal services generated for each data model passed to the MedusaService
function.
For example, if the BrandModuleService
is defined as follows:
Then, you can resolve the brandService
that allows you to manage brands in the module's loader:
1import {2 LoaderOptions,3} from "@medusajs/framework/types"4 5export default async function helloWorldLoader({6 container,7}: LoaderOptions) {8 const brandService = container.resolve("brandService")9 10 const brands = await brandService.list()11 12 console.log("[helloWorldLoader]: Brands:", brands)13}
Refer to the Service Factory reference for details on the available methods in the generated services.
Alternative to Resolving Other Modules' Services#
Since modules are isolated, you can't resolve resources that belong to other modules from the module's container. For example, you can't resolve the Product Module's service in the Blog Module's service.
Instead, to build commerce features that span multiple modules, you can create workflows. In those workflows, you can resolve services of all modules registered in the Medusa application, including the services of the Product and Blog modules.
Then, you can execute the workflows in API routes, subscribers, or scheduled jobs.
Learn more and find examples in the Module Isolation chapter.
Avoid Circular Dependencies#
When resolving resources in a module's services, make sure you don't create circular dependencies. For example, if BlogModuleService
resolves CmsService
, and CmsService
resolves BlogModuleService
, it will cause a circular dependency error.
Instead, you should generally only resolve services within the main service. For example, BlogModuleService
can resolve CmsService
, but CmsService
should not resolve BlogModuleService
.