2013-02-26 13 views
5

Właśnie zacząłem konfigurować nową aplikację ZF2 dla nowego projektu, opartego na szkielecie ZF2, i patrzę na ich samouczek na temat Models.Modele ZF2 udostępnione między modułami

tl; dr: jak powinienem udostępnić model między wieloma różnymi modułami, umieszczając go gdzieś na wyższym poziomie (na zewnątrz/moduł)?

Mamy kilka modułów setup tak:

/ 
/module/ModuleName 
/module/ModuleName/config 
/module/ModuleName/src 
/module/ModuleName/src/ModuleName 

Właśnie miałem do konfiguracji folderu /module/ModuleName/src/ModuleName/Model/TableName.php, ale potem zdałem sobie sprawę: że tabela będzie musiała być dostępne w innych modułach, jak również. Więc co powinienem zrobić?

Czy powinienem umieścić folder Modeli w /module/Model, czy też spowoduje to, że będzie traktowany jako moduł, np. Site.com/model (w oparciu o naszą obecną konfigurację).

Czy należy kopiować i wklejać modele między miejscami? Czy powinienem umieścić gdzieś modele w /vendor/library/Company/Model? Nie jestem pewien, czy jest na to najlepsza praktyka!

Pytanie 2: Samouczek sugeruje również użycie ServiceManager do utworzenia instancji modeli baz danych do korzystania z tej samej instancji. Co się stanie, jeśli mam moduł z 5 kontrolerami, a każdy kontroler uzyskuje dostęp do całkowicie oddzielnych tabel (powiedzmy po 4 tabele)? Wydaje mi się, że redundantnie zainicjowałoby 16 tabel przy każdym ładowaniu strony (dla innych kontrolerów w tym module). Inicjalizacja jednej tabeli powoduje dodanie 55ms do strony pageload. Czy jest jakiś sposób obejścia tego? Nie jestem pewien, jak przenieść konfigurację do działań kontrolera w oparciu o to, co samouczek ma zainicjować tablegateway?

Odpowiedz

8

1)

Można użyć dowolnego modelu z dowolnego modułu w aplikacji, więc można je „shared”. Na przykład użyj ServiceManager, aby pomóc ci pobrać instancje modeli (i innych klas) w twoim projekcie.

Service Manager Config:

'factories' => array(
    'AuthService' => function($sm) { 
     $auth = new \Zend\Authentication\AuthenticationService(); 

     return $auth; 
    }, 
    'RoleMapper' => function($sm) { 
     $dbAdapter = $sm->get('Zend\Db\Adapter\Adapter'); 
     $mapper = new \Application\Mapper\RoleMapper; 
     $mapper->setDbAdapter($dbAdapter); 
     $mapper->setEntityPrototype(new \Application\Model\Role); 
     $mapper->setHydrator(new \Application\Model\RoleHydrator); 

     return $mapper; 
    }, 
    'UserMapper' => function($sm) { 
     $dbAdapter = $sm->get('Zend\Db\Adapter\Adapter'); 
     $mapper = new \MyModule\Mapper\UserMapper; 
     $mapper->setDbAdapter($dbAdapter); 
     $mapper->setEntityPrototype(new \MyModule\Model\User); 
     $mapper->setHydrator($sm->get('UserHydrator')); 

     return $mapper; 
    }, 
    .... 

Jak widać można mieć zajęcia z wielu modułów określonych w tam. Zazwyczaj wystarczy zdefiniować oddzielną konfigurację ServiceManager dla każdego modułu.

Nie

nic powstrzymać się od dokonywania wystąpienie „UserMapper” wewnątrz modułu Application tak:

Niektóre Kontroler:

$this->getServiceLocator()->get('UserMapper'); 
// Or even grab Zend libraries like this 
$this->getServiceLocator()->get('AuthService'); 

ServiceManager pozwoli złapać instancje klas z dowolnego swoich modułów w którymkolwiek z pozostałych z problemem.

2)

Service Manager nie rzeczywiście zrobić wystąpienie niczego, dopóki nie poprosić go, więc nie ma nad głową, jak sugerujesz.

Z powyższym przykładzie, nie ma przypadków rzeczywiście stworzył aż najpierw poprosić o jednym:

$this->getServiceLocator()->get('UserMapper'); // instance now created. 

Jeśli nigdy nie zapytać Service Manager dla „RoleMapper” na przykład, to nie przypadek jest tworzony.

+0

Wielkie dzięki za odpowiedź Andrew! Masz rację: # 2, wygląda na to, że patrzyłem na niewłaściwą rzecz w Wincachegrind. Dobre wieści! Widziałem "UserMapper" wiele w kilku samouczków - czy to tylko przykład, czy jest to rzeczywiste ZF2 rzeczy? W odniesieniu do nr 1: więc jeśli zarejestruję funkcję 'Manufacturing \ Model \ WorkflowTable '=> ($ sm) {..}', czy będę mógł po prostu zadzwonić '$ this-> getServiceLocator() -> get() "Manufacturing \ Model \ WorkflowTable") "w dowolnej innej bibliotece? Czy standardową praktyką byłoby posiadanie modułu podstawowego z naszymi modelami? – Benno

+0

Tak, to jest pomysł, możesz wywołać go w dowolnym module, wszystkie Service Manager Configs są łączone ze sobą, dzięki czemu możesz uzyskać wszystko ze wszystkich modułów – Andrew

+0

UserMapper to tylko przykład, którego użyłem, jest to typowy scenariusz dla ludzi do korzystania z programu odwzorowującego DataMapper wzorzec – Andrew