antoine-coulon/effect-introduction

Qestion: banana gorilla jungle problem with DI

DScheglov opened this issue ยท 4 comments

Hi there,

I've noticied the potential problem in the REAMDE sample:

interface UserService {
  createUser: () => Effect.Effect<UserService, UserAlreadyExistsError, CreatedUser>;
}

code

The question is:

  • is it a typo or is it inteded to have the Effect depnding on the UserService as a result of the createUser?

I expect something like that:

interface IUserCreator {
  createUser: () => Effect.Effect<never, UserAlreadyExistsError, CreatedUser>
}

I guess it is expected that calling userService.createUser returns an effect without a dependency on the { createUser }, that later could be run without provisioning of any dependencies.

The more realistic case looks like that:

interface IUserCreator {
  createUser: () => Effect.Effect<DBConnection, UserAlreadyExistsError, CreatedUser>
}

The UserService.createUser returns an Effect depends on the DBConnection but not on the UserService

Hello @DScheglov,

Nice catch, it's indeed a mistake, the createUser is just there to simulate a dummy business use-case and the UserService should indeed be named UserRepository so that the use-case depends on the repository but the type parameter R from the createUser of the repository should be never, or as you mentioned could contain something representing the DB connection (even if the latter could be hidden from the Effect signature and be indeed part of the service lifecycle).

Consequently this would be something like:

// use case
const registerUser: Effect<UserRepository, UserRegistrationError, DomainUser> = {}

interface UserRepository {
  createUser: () => Effect<never, UserAlreadyExistsError, CreatedUser>,
  // or
  createUser: () => Effect<DBConnection, UserAlreadyExistsError, CreatedUser>
}

I'll update the example to get rid of the mistake and change the naming to avoid introducing confusion

Thanks for you feedback!

@DScheglov just updated the introduction on the DI part. Thanks for the heads up!
FYI I didn't end up mentioning any other dependency for the repository, just stayed on the most simple case where resources are managed within the service itself, so not visible from the interface.

@antoine-coulon ,
Thank you for your job. Effect is really cool and Intro to the Effect is something must to have.

I'm going to deep dive in DI with Effect, so it could be I will create a new issues (perhaps in the Effect repo) :)

Currently it seems the "client" must be aware of the dependencies of the "service" it depends on even if it depends on abstraction -- it is not desired in the DI. But let's keep it for another issue

Thanks :)

Of course feel free to create new issues if it's related to the introduction in itself, but at some point it might eventually make more sense to discuss about core concepts on the Effect Discord. It's also worth to note that some of your questions are already answered there as the community and especially the maintainers are very active.

Currently it seems the "client" must be aware of the dependencies of the "service" it depends on even if it depends on abstraction -- it is not desired in the DI. But let's keep it for another issue

Not sure to understand your point there, DI is used to decouple the usage of dependencies from their actual creation process, in that case the usage of dependencies is made explicit as we want it to be, without telling anything about when/how the dependency is itself constructed hence keeping the abstraction intact.