# Providing Services via Layers
You have a trait. You have an implementation. Now you need a Layer that wires them together.
## The Minimal Service Layer
```rust
use id_effect::{LayerFn, tagged, effect};
// The production implementation
struct PostgresUserRepository {
pool: Pool,
}
impl UserRepository for PostgresUserRepository {
fn get_user(&self, id: u64) -> Effect<User, DbError, ()> {
effect! {
let row = ~ query(&self.pool, "SELECT * FROM users WHERE id = $1", id);
User::from_row(row)
}
}
// ...
}
// The layer that builds the implementation from the database pool
let repo = PostgresUserRepository { pool: env.value().clone() };
tagged::<UserRepositoryTag>(Arc::new(repo) as Arc<dyn UserRepository>)
}
});
```
The layer takes `Tagged<DatabaseKey>` (the database pool) and produces `Tagged<UserRepositoryTag>` (the repository wrapped as `Arc<dyn UserRepository>`).
## Composition with Other Layers
The repository layer needs the database. Wire them:
```rust
let app_layer = config_layer
.stack(db_layer)
.stack(user_repo_layer); // db_layer output feeds into user_repo_layer
```
Now `app_layer` produces an environment containing `ConfigKey`, `DatabaseKey`, and `UserRepositoryTag` — everything `get_user_profile` needs.
## Test Layer with Mock
```rust
struct MockUserRepository {
users: HashMap<u64, User>,
}
impl UserRepository for MockUserRepository {
fn get_user(&self, id: u64) -> Effect<User, DbError, ()> {
match self.users.get(&id) {
Some(u) => succeed(u.clone()),
None => fail(DbError::NotFound),
}
}
// ...
}