0

I have two service classes like below...

User Service:

class UserService { dao: UserGroupDao =>
 ...
 def read(userId: String): Future[Option[User]] = dao.readUser(userId)
 ...
}

Group Service:

class GroupService {dao: UserGroupDao =>
 def createGroup(group: Group): Future[Either[String, String]]) = {
  val userService = new UserService() with UserMysqlDao
  userService.read(group.ownerId) map {
   case Some(u) => dao.createGroup(group)
   case None => Left("Invalid User!")
  }
 }
 ...
}

I am just validating if the owner of the group is a valid user. For that I reused the userService.read method with a hardcoded Dao Implementation i.e. UserMySqlDao.
Here my question is instead of providing hardcoded Dao Impl how could I use the groupservice's dao object. because the type are same for UserService and GroupService.

I tried using the following

val userService = new UserService with dao

but this failed. I am new to scala hence, not really clear why this failed. It would be helpful if someone can put some light on why this is not legal.

Thanks in Advance :)

ArunavaS
  • 197
  • 1
  • 12

2 Answers2

1

If I understand right your question, you're looking for a solution for multiple dependencies declaration using the Cake Pattern.

The solution commonly used is to define a new type, a component, that contains references to all the dependencies that you need. In your specific case, the story will be the following.

trait GroupServiceComponent {
  val userService: UserService
  val userGroupDao: UserGroupDao

  class GroupService {
    def createGroup(group: Group): Future[Either[String, String]]) = {
      userService.read(group.ownerId) map {
        case Some(u) => userGroupDao.createGroup(group)
        case None => Left("Invalid User!")
      }
    }
  }
}

Let me know if you need more information.

riccardo.cardin
  • 7,971
  • 5
  • 57
  • 106
0

Just thought I'd have a play around for fun and see what I could get to compile. Not sure that this is a good solution or even good style but my thought was to have the GroupService depend on a UserService, that made it's dao public.

class UserService { d: UserGroupDao =>
  val dao = d
  def read(userId: String): Future[Option[User]] = dao.readUser(userId)
}

class GroupService { svc: UserService =>
  def createGroup(group: Group): Future[Either[String, String]] = {
    svc.read(group.ownerId) map {
      case Some(_) => svc.dao.createGroup(group)
      case None => Left("Invalid User!")
    }
  }
}
Gary
  • 46
  • 2
  • yeah... but suppose if group gonna have it's own different dao, then this will fail... cake pattern with component would work there... Also, to me not a good approach to lend the dao from another service for it's own operations... what say? – ArunavaS Dec 10 '16 at 06:24