我正在做一个漂亮的项目,我试图让我的数据库层可以在不同的配置文件之间轻松交换,以便在内存数据库上编写测试。这个问题的灵感来自这个问题,但它与 slick 本身没有任何关系。
我对依赖类型没有丰富的经验,在我的例子中,我有以下特征,我用它来从数据库中抽象出一些类型:
trait Types {
type A <: SomeType
type B <: SomeOtherType
val bTag: ClassTag[B]
}
然后我有另一个特征,基本上是我的(人造)蛋糕图案的一部分:
trait BaseComponent {
type ComponentTypes <: Types
val a: Types#A
implicit val bTag: ClassTag[Types#B]
}
然后我有一个组件的实际实现,如下所示:
trait DefaultTypes {
type A = SomeConcreteType
type B = SomeOtherConcreteType
val bTag = implicitly[ClassTag[B]]
}
trait DefaultBaseComponent extends BaseComponent {
type ComponentTypes = DefaultTypes
val ct = new ComponentTypes {}
implicit val bTag = ct.bTag
}
我需要该标签,因为稍后服务将需要它(在我的实际实现中,我使用这种类型来抽象不同数据库库抛出的不同类型的异常);我很确定有更好的方法来做我想做的事情。
如果我没有实例化ComponentTypes
特征以获取标记,并且我在 DefaultBaseComponent 中移动隐式召唤代码,它将召唤 anull
代替ClassTag
. 我需要有一种方法来引用我正在使用的实际类型(不同的A
以及B
我在不同环境中拥有的类型),并且我需要在其他组件中执行它而不知道它们是哪些实际类型。
我的解决方案有效,编译并通过了我为它编写的所有测试,谁能帮助我让它变得更好?
谢谢!