0

I have simple service classes

trait ItemService[+A] {
  def getItem(id: Int): Option[A]
}
class MockItemService(implicit inj: Injector) extends ItemService[Item] with Injectable      {
  def getItem(id: Int) =  {
     Option(new Feature("My Headline",Author(2,"Barry White")))
  }
}

using scaldi im binding MockItemService to ItemService then accessing like

class Features(implicit inj: Injector) extends Controller with Injectable {
   val itemService = inject [ItemService[Item]]
   def item(cat:String, id:Int, urlTitle:String) = Action {   
      itemService.getItem(id).map { item => Ok(views.html.feature.item(item))      
   }.getOrElse(NotFound)    
  }  
}

what i want is for item to be of type Feature and not Item. Feature extends Item.

doniyor
  • 36,596
  • 57
  • 175
  • 260
AdiFatLady
  • 368
  • 1
  • 6
  • 18
  • 3
    Quite unclear. You specifically ask for having instance of service returning `Option[Item]` from `getItem`, so what? Either you want a service managing `Feature` and so the injection must be updated accordingly (replacing `Item`), or your `Feature` type is a subtype of `Item` and you can use pattern matching to dispatch this case? I think you need to make it clearer to get right answer. – cchantep Aug 07 '14 at 22:43
  • I want a service that returns specific objects that are sub types of Item e.g. NewsItem, ReviewItem etc. I dont want to have to do getFeature etc. At some point i need to deal with the specific type of Item though. – AdiFatLady Aug 09 '14 at 20:34

2 Answers2

0
    class Features(implicit inj: Injector) extends Controller with Injectable {
      val itemService = inject [ItemService[Item]]

      def item(cat:String, id:Int, urlTitle:String) = Action {
        itemService.getItem(id).map { item =>
           item match {
             case Feature(itsAFeature) => Ok(views.html.feature.item(itsAFeature))
             case itsAnItem => ???
           }
        }.getOrElse(NotFound)
      }
    }
Rado Buransky
  • 3,252
  • 18
  • 25
0

I found this worked

  itemService.getItem(id).map { item =>
       item match {
         case x: Feature => Ok(views.html.feature.item(x))
         case _: Any => NotFound
       }
    }.getOrElse(NotFound)

It still feels a bit clunky. I basically want getItem to return different types of objects that are all sub types of Item but at some point i will need to deal with the specific type of object. I could do getFeature etc but i may not know the type before i call getItem. If the controller doesnt need to know the specifics then surely its a good idea it doesnt.

AdiFatLady
  • 368
  • 1
  • 6
  • 18
  • Case `_` doesn't need type: `case _ => ???` and it can be directly in map: `.map { case x: Feature => ??? }`. – cchantep Aug 11 '14 at 07:58