# A service captures its construction dependencies

> For agents: start with the [agent guide](https://ratstack.sh/llms.txt). Every page is Markdown by default; add `Accept: text/html` for HTML.

Free workshop: [how to burn a trillion tokens and get good results](/tokenmaxx#interested).

Build a service once with the dependencies its implementation needs. Return methods that use those captured values.
Callers then require only the service.

## Name the job before the implementation

`Context.Service` names a service and describes its interface.
`Effect.Effect<FileStats, FileStatsError>` declares the method's success and expected failure. Its omitted requirement parameter is `never`.

packages/core/src/file-inspector.ts at 65e9465f38092e24486392f22c08f45d61230c20; lines 6-15; highlighted none.

```typescript
export class FileInspector extends Context.Service<
  FileInspector,
  {
    readonly inspect: (
      path: string
    ) => Effect.Effect<FileStats, FileStatsError>;
  }
>()("@rat-stack/core/FileInspector", {
  make: Effect.gen(function* makeFileInspector() {
    const fileSystem = yield* FileSystem.FileSystem;
```

`make` describes service construction as an Effect.
`Layer.effect` runs that construction when the service graph is built.

## Compose work inside the method

Use `Effect.gen` for inline composition. Use `Effect.fn("name")` for reusable functions that need a tracing boundary.
Use `Effect.fnUntraced` when tracing is not useful.
Do not create a function that only returns another `Effect.gen` wrapper.

packages/core/src/file-inspector.ts at 65e9465f38092e24486392f22c08f45d61230c20; lines 17-35; highlighted none.

```typescript
    const inspect = Effect.fn("FileInspector.inspect")(function* inspect(
      path: string
    ) {
      const content = yield* fileSystem
        .readFile(path)
        .pipe(
          Effect.mapError(
            (error) => new FileStatsError({ path, reason: error.message })
          )
        );

      return summarizeBytes(path, content);
    });

    return { inspect } as const;
  }),
}) {
  static readonly layer = Layer.effect(this, this.make);
}
```

`inspect` closes over the filesystem value. It keeps read failures typed and returns a domain result.

The service method composes Effects. It does not run an imperative runtime inside the computation.

## Construction dependencies are not request identity

Methods can retain contextual requirements when the job needs them.
A filesystem implementation usually belongs to construction. A current person may belong to a single request.

Pass request data explicitly, or keep that requirement visible at the request boundary.
Do not capture one request's identity in a service shared by later requests.

[Issue #24](https://github.com/kitlangton/effect-solutions/issues/24) records the risk of treating dependency-free methods as universal law.

## Common wrong approach

Resolving the filesystem inside every `inspect` call leaves `FileSystem` in that method's requirements.
The caller must now know the implementation dependency. Capturing it during construction removes that requirement from the method.

Rebuilding the service inside every call also loses the intended construction lifetime.
Supply its Layer at the [composition root](/lore/layers-make-dependencies-explicit).

## Effect idiom and house rule

- Services describe behavior. Layers supply implementations and resolve construction requirements.
- In rat-stack, keep `make` and `static layer` beside the service. Core owns job-shaped ports; adapters own provider code.
- rat-stack also uses capability projections, cartridge packages, and a no-comments rule.

See also: [domain structure](/lore/structure-effect-by-domain), [Layer composition](/lore/layers-make-dependencies-explicit), [the Layer constructor pattern](/lore/layer-constructor-pattern), and [testing through services](/lore/tests-that-earn-their-place).

## Sources

1. [Effect contributors. 2026. Context. Effect 4.0.0.](https://github.com/Effect-TS/effect/blob/67ba4e46a11ccda0b6761578bfd22c04ae00167d/packages/effect/src/Context.ts)
   Effect-TS. Context.Service supports a typed interface and an effectful make operation. Accessed 2026-10-06.

2. [Effect contributors. 2026. Composing services with the Layer module.](https://github.com/Effect-TS/effect/blob/67ba4e46a11ccda0b6761578bfd22c04ae00167d/ai-docs/src/01_effect/03_services/20_layer-composition.ts)
   Effect-TS. Construction captures dependencies before returning Effect.fn methods. Accessed 2026-10-06.

3. [Effect contributors. 2026. Effect. Effect 4.0.0.](https://github.com/Effect-TS/effect/blob/67ba4e46a11ccda0b6761578bfd22c04ae00167d/packages/effect/src/Effect.ts)
   Effect-TS. Effect.gen composes inline work; fn names traced functions; fnUntraced avoids tracing. Accessed 2026-10-06.

4. [rat-stack contributors. 2026. FileInspector.](https://github.com/joelhooks/rat-stack/blob/65e9465f38092e24486392f22c08f45d61230c20/packages/core/src/file-inspector.ts)
   rat-stack. The service captures FileSystem in make and exposes an inspect method without filesystem requirements. Accessed 2026-10-06.

5. [Langton, Kit. 2026. Services & Layers. Effect Solutions.](https://github.com/kitlangton/effect-solutions/blob/09f82e6c5c928e7232cd32daf04d7c6a830b63f7/packages/website/docs/04-services-and-layers.md)
   Kit Langton. Topic framing for service interfaces, dependency capture, and replaceable implementations; examples checked against Effect 4.0.0. Accessed 2026-10-06.

6. [Effect Solutions contributors. 2025. Clarify that there could be exceptions on methods having dependencies.](https://github.com/kitlangton/effect-solutions/issues/24)
   Effect Solutions. Reader concern about request-time context and universal dependency-free method advice. Accessed 2026-10-06.

## Lore on this page

- [Cartridges](/lore/cartridges)

## Linked from

- Agent guide → An Effect stack so pure (aspirational) Kit Langton will blush. → [Read page](https://ratstack.sh/llms.txt)

- Change log → What changed in the files served here, newest first. → [Read page](https://ratstack.sh/log)

- Configuration is a supplied, validated dependency → Parse configuration when a Layer builds, reject invalid values, and supply controlled settings in tests. → [Read page](https://ratstack.sh/lore/configuration-is-a-dependency)

- Effect basics → An Effect describes work, expected failures, and required services before a runtime executes it. → [Read page](https://ratstack.sh/lore/effect-basics)

- Effect keeps the surfaces on one contract → Schema owns values, projections build interfaces, and Layers supply implementations. → [Read page](https://ratstack.sh/lore/how-we-do-it-with-effect)

- Full agent guide → An Effect stack so pure (aspirational) Kit Langton will blush. → [Read page](https://ratstack.sh/llms-full.txt)

- Layer composition makes dependencies explicit → Supply a service's dependencies, choose which services remain visible, and reuse Layer identity within a build. → [Read page](https://ratstack.sh/lore/layers-make-dependencies-explicit)

- learn-rat-stack → Trace a capability through Effect, XState, five projections, the CLI, and Alchemy. Try hosted search and read. → [Read page](https://ratstack.sh/skills/learn-rat-stack)

- Rat Stack lore | rat-stack → Short, source-grounded notes on the ideas and decisions behind rat-stack. → [Read page](https://ratstack.sh/lore)

- Run Effect at the integration boundary → Build the runtime where foreign code enters, reuse its services, and dispose it when that integration ends. → [Read page](https://ratstack.sh/lore/run-effect-at-the-boundary)

- Schemas define the boundary → Define accepted data with Schema, decode unknown input before dispatch, and encode results through the declared contract. → [Read page](https://ratstack.sh/lore/schemas-define-the-boundary)

- Source change history (log.md) → The generated change log as Markdown. → [Read page](https://ratstack.sh/log.md)

- Structure an Effect codebase by domain → Start with domain folders, colocated services and Layers, and one composition root per entrypoint. → [Read page](https://ratstack.sh/lore/structure-effect-by-domain)
