2016-04-20 7 views
3

Ich bin an Frameworks wie Ruby on Rails oder Laravel in PHP, wo ich Modelle wie User und wenn ich eine Abfrage an das Modell (zum Beispiel, um alle Benutzer in der Datenbank) mache ich etwas wie User::all().Spiel für Scala: Scala-Objekt als DAO

Ich bin neu für Scala und Slick zu spielen, und alle Projekte und Dokumentation, die ich bereits gesehen habe, verwenden ein DAO für den Zugriff auf die Datenbank über ein Modell. Ich habe gedacht, dass eine Scala object ist, was ich brauche (oder zumindest bin ich daran gewöhnt), so dass ich DAO-Klassen nicht überall injizieren muss.

Mit einem DAO ich etwas wie folgt aus:

class Application @Inject()(adminDAO: AdminDAO) extends Controller { 
    def index = Action.async { 
    adminDAO.all() map { case admins => 
     Ok(Json.toJson(admins)) 
    } 
    } 
} 

Und mit einem Objekt (und keine Ahnung) erwarte ich, so etwas zu tun:

class Application extends Controller { 
    def index = Action.async { 
    Admin.all() map { case admins => 
     Ok(Json.toJson(admins)) 
    } 
    } 
} 

Der Versuch, die „DAO zu implementieren "object Ich habe fast unmöglich gefunden, den Play Application Kontext zu injizieren, ohne Play.current zu verwenden, was veraltet ist. Diese Art von Abwertung und das Fehlen einer Möglichkeit, den Kontext zu injizieren (oder zumindest habe ich ihn nicht gefunden), klingt für mich seltsam. Ich fange an zu denken, dass ich es falsch denke. Ist es wirklich eine gute Idee, ein Scala object als DAO zu verwenden?

+0

Sie können sich auch [Anorm] (https://www.playframework.com/documentation/2.5.x/ScalaAnorm) ansehen. – cchantep

Antwort

3

Es kommt auf Dependency Injection (DI) vs hardcoding Abhängigkeiten. In Ihrem ersten Beispiel wird DI verwendet, während Ihr zweites die Abhängigkeit von der Admin DAO fest codiert. Das Play-Team hat beschlossen, mit DI in der letzten Releases in dem Bemühen, gehen globalen Zustand zu entfernen (für eine Diskussion, warum globaler Zustand eine schlechte Sache sieht here for example ist):

Jetzt spielen, aus der Box verwendet Abhängigkeit Injektion von Guice zur Verfügung gestellt. Dies ist Teil einer langfristigen Strategie, um den globalen Status aus Play zu entfernen, die wir in der Play 3.0-Version abschließen möchten.

Source

Daher ist der richtige Weg, wenn es zu spielen kommt, ist Ihr Beispiel 1, ein Objekt mit Hilfe und damit eine hartcodierte Abhängigkeit ist in der Tat nicht ratsam rein auf der Grundlage der Tatsache, dass man gegen Spiel arbeiten (aber DI hat viele Vorteile auch).

Ich bin nicht gut in Ruby, aber soweit ich weiß DI mit Frameworks (zB Guice) wie es in Java/Scala kommt wird nicht benötigt, da Ruby bestimmte Sprachfeatures hat, um das Problem anders zu lösen, was Vielleicht wundern Sie sich über den ganzen Punkt von allem. Ich empfehle Ihnen, ein wenig über Dependency Injection in einem Java/Scala-Kontext zu lesen, das sollte klären, wie es funktioniert, welche Probleme es löst und welche Vorteile es hat (und da Sie Ruby kennen, warum es nicht benötigt wird) Ruby auf die gleiche Weise).

Der Versuch, das „DAO“ Objekt zu implementieren ich fast unmöglich zu gefunden haben, die Play-Anwendungskontext zu injizieren, ohne Play.current , die veraltet ist. Diese Art von Abwertung und das Fehlen eines Weges des Injizierens des Kontextes (oder zumindest habe ich es nicht gefunden) klingt seltsam für mich.

Sie sollten in der Lage sein, einfach den Anwendungskontext in Ihr DAO zu injizieren, z.wie folgt:

class AdminDao @Inject()(val application : Application) { 

und dann haben Sie die Anwendung zur Verfügung. Dies ist das Äquivalent zu der veralteten

val application = Play.current 

In beiden Fällen müssen Sie die Lauf Application erfassen. Das Framework für die Abhängigkeiteninjektion stellt sicher, dass Abhängigkeiten rekursiv aufgelöst werden, d. H. Wenn Sie von Ihrem DAO in einem Controller abhängig sind, stellt es fest, dass das DAO selbst von der Anwendung abhängt. Es löst die Anwendung auf, injiziert sie in eine neue DAO-Instanz und fügt sie schließlich in Ihren Controller ein.

Und last but not least führen viele Wege nach Rom wie immer: Vielleicht ist ActiveSlick etwas, das Sie nützlich finden (Disclaimer: Habe es nicht selbst ausprobiert).

+0

Danke für die Klarstellung für den ersten Teil (DI gegen globalen Zustand), aber im zweiten Teil der Antwort ist das Problem, dass ich den 'Application' Kontext in einem Scala' Objekt' brauche, also habe ich keinen Konstruktor verfügbar, um die Abhängigkeit zu injizieren. Da die DAO eine 'Klasse' verwendet, gibt es überhaupt kein Problem. Wie würdest du es lösen? – soutoner

+0

Sie möchten kein Objekt verwenden, weil Sie dann den globalen Status erneut verwenden (-> eine DAO-Instanz, die von allen davon abhängigen Klassen verwendet wird). Sie möchten eine Klasse, so generiert das Framework für jede davon abhängige Klasse individuelle DAO-Instanzen -> kein globaler Status mehr. DI in einem Spiel-Kontext kommt mit dem ganzen Klassen-Konstruktor-Injekt-Muster, so wie es ist zu schreiben (ich stimme hier zu). Das Einfügen in Objekte funktioniert einfach nicht, da das Framework die Instanzen nicht generieren und keine Abhängigkeiten auflösen kann. – alextsc

+0

Perfekt! danke für solch eine tiefe Antwort, ich werde Klassen als DAO verwenden, da dies der bevorzugte Weg von Play ist. – soutoner