PlayFramework. Dostęp do klas między modułami

0

Witam.
Tworzę apllikację w PlayFramework. Tworzę ją na bazie kilku modułów:
/modules/common
/modules/shopping
/modules/admin

Główny moduł nie ma żadnego kodu.

Wszystko działa ok, do momentu kiedy chcę wywołać klasę pomiędzy modułami. np:
Z widoku /modules/common/app/views wywołuje klasę /modules/shopping/app/controllers/Index.java

			<a href="@controllers.shopping.routes.Index.index">

Dostaje błąd:
object shopping is not a member of package controllers

W jaki sposób mogę w play wywoływać klasy z podmodułów?

mój główny build.sbt

import play.Project._
import sbt._
import Keys._
name := "svp"

playJavaSettings

version := "2.0.0_(20140725)"

libraryDependencies ++= Seq(
  javaJdbc, 
  javaJpa, 
  "org.hibernate" % "hibernate-entitymanager" % "3.6.9.Final",
  "mysql" % "mysql-connector-java" % "5.1.27",
  "org.mindrot" % "jbcrypt" % "0.3m",
  cache
  )

  lazy val common = project.in(file("modules/common"))
  lazy val cirs = project.in(file("modules/cirs"))
  lazy val shopping = project.in(file("modules/shopping"))
  lazy val admin = project.in(file("modules/admin"))


val main = project.in(file("."))
  .dependsOn(common).aggregate(common)
  .dependsOn(cirs).aggregate(cirs)
  .dependsOn(shopping).aggregate(shopping)
  .dependsOn(admin).aggregate(admin)

Pozostałe pliki build dla poszczególnych modułów:
/modules/shopping/build.sbt:

name := "shopping"

playJavaSettings

Common.settings

libraryDependencies ++= Seq(
  javaJdbc, 
  javaJpa, 
  "org.hibernate" % "hibernate-entitymanager" % "3.6.9.Final",
  "mysql" % "mysql-connector-java" % "5.1.27",
  "org.mindrot" % "jbcrypt" % "0.3m",
  cache
  )

/modules/common/build.sbt:

name := "common"

playJavaSettings

Common.settings

libraryDependencies ++= Seq(
  javaJdbc, 
  javaJpa, 
  "org.hibernate" % "hibernate-entitymanager" % "3.6.9.Final",
  "mysql" % "mysql-connector-java" % "5.1.27",
  "org.mindrot" % "jbcrypt" % "0.3m",
  cache
  )

Podczas edycji widoku eclipse mi podpowiada pozostałe moduły (w załączniku print screen)

OPIS ZALEŻNOŚCI MIĘDZY MODUŁAMI
Moduł common: ma służyć jako zbiór elementów, klas, obiektów wspólnych dla pozostałych modułów/ aplikacji
Przykładowe klasy (MVC): użytkownicy, klienci, uprawnienia, role,

Pozostałe moduły mają być dedykowane konkretnej funkcji/aplikacji, np. Stworzę moduły (pod aplikacje) do:

  • zarządzania treścią strony (CMS),
  • przeprowadzania sprzedaży (Sklep),
  • zarządzania relacjami z klientem (CRM)
  • zarządzania wszystkimi aplikacjami (kontami użytkowników, rolami, uprawnieniami, etc.)

Wszystkie te pod moduły będą korzystały z modułu common.

Po zalogowaniu się użytkownik zobaczy stronę wyboru aplikacji/ modułu (zgodnie z uprawnienaimi).
Będą tam linki do tych aplikacji, np:

			<a href="@controllers.shopping.routes.Index.index">Sklep</a>
			<a href="@controllers.crm.routes.Index.index">CRM</a>
			<a href="@controllers.cms.routes.Index.index">Zarządzanie stronami</a>
			<a href="@controllers.admin.routes.Index.index">Panel administracyjny</a>

Aby je utworzyć moduł common musi mieć dostęp (dependsOn()) do pozostałych modułów, ponieważ kontrolery odwrotnego routingu są w konkretnych modułach!!!

Jeżeli użytkownik znajdzie się już w wybranym module/aplikacji zobaczy np: panel ze swoimi danymi (imię, nazwisko, grupa, rola, etc), które będą pobierana z modułu common z klas typu: User.java, Role.java etc.

0

Wszystko robię zgodnie z tym tutorialem.
Problem leży w tym, że sbt podczas budowania nie widzi klas z pozostałych modułów.
Gdybym zastąpił tą ścieżkę na ścieżkę należącą do tego samego modułu/pakietu, np:

<a href="@controllers.common.routes.Index.index">

Wszystko jest ok.

Pytanie moje brzmi: W jaki sposób mogę się odwoływać do klas z pozostałych modułów?

1

Żeby z modułu commons dostać się do klas z modułu shopping, to moduł commons musiałby mieć dependsOn(shopping). Ale to jest wbrew logice - zwykle to commons jest modułem od którego się zależy, a nie odwrotnie.

Zresztą pod tym linkiem co Szczery podał jest sekcja "Splitting your web application into several parts" gdzie jest pokazane jak się to dependsOn ustawia.

0

Ok. Przemyślałem jeszcze raz projekt. I udało mi się ustawić aby common widział klasy pozostałych pakietów

lazy val cirs = project.in(file("modules/cirs"))
  	
  lazy val shopping = project.in(file("modules/shopping"))
  	
  lazy val admin = project.in(file("modules/admin"))

  lazy val common = project.in(file("modules/common"))
  .dependsOn(cirs).aggregate(cirs)
  .dependsOn(shopping).aggregate(shopping)
  .dependsOn(admin).aggregate(admin)

val main = project.in(file("."))
  .dependsOn(common).aggregate(common)
  .dependsOn(cirs).aggregate(cirs)
  .dependsOn(shopping).aggregate(shopping)
  .dependsOn(admin).aggregate(admin)

Tylko jak teraz ustawić aby pozostałe pakiety miały dostęp do common?

0

Chcesz mieć cykliczne zależności między modułami? Tak się nie da. Poczytaj o inżynierii oprogramowania, jakieś podstawy chociaż, bo popełniasz szkolne błędy.

0

Użyj jakiejś formy wstrzykiwania zależności. Na przykład: utwórz moduł, który zależy od wszystkich innych i zawiera widok z linkami do tych widoków, które potrzebuje, a następnie wstrzyknij ten widok w reszcie aplikacji.

Widok w Playu sprowadza się do klasy generującej obiekt typu Html, który to obiekt można podawać jako parametr do kolejnych widoków i bezpośrednio w nich wklejać zawartość przekazanego wyrenderowanego widoku.

0

Adresy na tym widoku zrobię ręcznie (localhost/shop).
Natomiast resztę modułów ustawię zależne od common ".dependsOn(common)", mam nadzieję, że więcej nie będę potrzebować dostępu z common do pozostałych modułów :D.

1 użytkowników online, w tym zalogowanych: 0, gości: 1