Skip to content

Commit a35fe10

Browse files
authored
add "Effect.Service vs Context.Tag" section (#1160)
1 parent de7e879 commit a35fe10

File tree

1 file changed

+28
-0
lines changed
  • content/src/content/docs/docs/requirements-management

1 file changed

+28
-0
lines changed

content/src/content/docs/docs/requirements-management/layers.mdx

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1203,3 +1203,31 @@ Effect.runPromise(program.pipe(Effect.provide(Sync.Default)))
12031203
<Aside type="caution" title="Limitation of Direct Method Access">
12041204
Direct method access does not work with generic methods.
12051205
</Aside>
1206+
1207+
### Effect.Service vs Context.Tag
1208+
1209+
Both `Effect.Service` and `Context.Tag` are ways to model services in the Effect ecosystem. They serve similar purposes but target different use-cases.
1210+
1211+
| Feature | Effect.Service | Context.Tag |
1212+
| ----------------------------------- | ------------------------------------------------------- | ----------------------------------------- |
1213+
| Tag creation | Generated for you (the class name acts as the tag) | You declare the tag manually |
1214+
| Default implementation | **Required** - supplied inline (`effect`, `sync`, etc.) | **Optional** - can be supplied later |
1215+
| Ready-made layers (`.Default`, ...) | Automatically generated | You build layers yourself |
1216+
| Best suited for | Application code with a clear runtime implementation | Library code or dynamically-scoped values |
1217+
| When no sensible default exists | Not ideal; you would still have to invent one | Preferred |
1218+
1219+
**Key points**
1220+
1221+
- **Less boilerplate:** `Effect.Service` is syntactic sugar over `Context.Tag` plus the accompanying layer and helpers.
1222+
- **Default required:**
1223+
A class that extends `Effect.Service` must declare **one** of the built-in constructors (`effect`, `sync`, `succeed`, or `scoped`). This baseline implementation becomes part of `MyService.Default`, so any code that imports the service can run without providing extra layers.
1224+
That is handy for app-level services where a sensible runtime implementation exists (logging, HTTP clients, real databases, and so on).
1225+
If your service is inherently contextual (for example, a per-request database handle) or you are writing a library that should not assume an implementation, prefer `Context.Tag`: you publish only the tag and let callers supply the layer that makes sense in their environment.
1226+
- **The class _is_ the tag:** When you create a class with `extends Effect.Service`, the class constructor itself acts as the tag. You can provide alternate implementations by supplying a value for that class when wiring layers:
1227+
1228+
```ts
1229+
const mock = new MyService({
1230+
/* mocked methods */
1231+
})
1232+
program.pipe(Effect.provideService(MyService, mock))
1233+
```

0 commit comments

Comments
 (0)