Effect CommunityEC
Effect Community3y ago
10 replies
hdoro

Comparison of Context/Services and Plain Functions for Dependency Injection and Testing

I'm trying to get my head around Context/Services. Currently, I'm solving dependencies with pipes and flatMaps, passing them to regular functions that return new effects.

It feels context is slightly more verbose and complicated to understand, and with plain functions & dependencies I can still get the benefits of dependency injection and isolation for testing, no?

I've attached the full happy-path of my program, but here's a quick comparison as I'm seeing it:

// Pipe-based w/ plain function arguments
pipe(
Effect.flatMap((data) => {
  return pipe(
    Effect.retry(createPhraseProject(data.request), retrySchedule),
    Effect.map((project) => ({
      ...data,
      project,
    })),
  )
}),
Effect.flatMap((data) => {
  return pipe(
    Effect.retry(createPhraseJobs(data), retrySchedule),
    Effect.map((jobs) => ({
      ...data,
      jobs,
    })),
  )
}))

// Service-based - is this even right?
Effect.all([TranslationRequest, FreshDocuments]).pipe(
  Effect.flatMap(([request, freshDocuments]) =>
    Effect.retry(createPhraseProject(request), retrySchedule),
  ),
  Effect.flatMap((project) =>
    Effect.provideService(
      Effect.all([TranslationRequest, FreshDocuments, PhraseProject]).pipe(
        // Following step, nested inside the provideService
        // ...
      ),
      PhraseProject,
      PhraseProject.of(project),
    ),
  ),
)


What am I missing? What's a better way to use context for sequential data increments?
Was this page helpful?