This is not framework- (or lack thereof) dependent, but one Scalish move would be to inject the association as a function instead of as a Map. A Scala Map is also a function.
Given boring Type tokens and instances of T to associate:
scala> object Types extends Enumeration { val AType, BType, CType = Value }
defined object Types
scala> import Types._
import Types._
scala> trait T { def t: String }
defined trait T
scala> case class A(t: String = "a") extends T
defined class A
scala> case class B(t: String = "b") extends T
defined class B
scala> case class C(t: String = "c") extends T
defined class C
And an app with a function that uses it:
scala> trait AnApp { val types: Value => T ; def f(t: Value) = types(t).t }
defined trait AnApp
Then inject it as a Map:
scala> object MyApp extends AnApp { val types = Map(AType -> A("a1"), BType -> B(), CType -> C()) }
defined object MyApp
scala> MyApp f BType
res0: String = b
or a pattern matching anonymous function:
scala> object AnotherApp extends AnApp { val types: Value => T = {
| case AType => A("a2") case BType => B() case CType => C() } }
defined object AnotherApp
scala> AnotherApp f CType
res1: String = c
actually it's more convenient to use def
:
scala> trait AnApp { def types: Types.Value => T ; def f(t: Types.Value) = types(t).t }
defined trait AnApp
scala> object AnyApp extends AnApp { def types = {
| case AType => A("a2") case BType => B() case CType => C() } }
defined object AnyApp
You don't get the type inference with a val, but I seem to remember they wanted to add that.