Hmmm... I usually have small "manager" services wrapped around the ObjectManager so I can easily swap out those when needed. But I guess that does couple them to Doctrine a bit tighter then using repositories like you describe. I'm going to give this some thought.
PS: I do try to keep an eye out for over-enginering. Most project I work on don't really need perfect abstraction ;) -- Jasper N. Brouwer (@jaspernbrouwer) On 3 Feb 2014, at 16:07, Marco Pivetta <[email protected]> wrote: > On 3 February 2014 15:51, Jasper N. Brouwer <[email protected]> wrote: >> When I have a service that needs a Repository and/or >> (Entity/Document)Manager, I inject the Manager. From the Manager I can get >> the Repository I need. This way I can simple inject 1 dependency (the >> Manager), regardless of how many repositories are actually used. I also >> don't need to implement Repositories as services (in order to inject them). > > That increases coupling with the entity manager (object manager) as a locator > for repositories, making it very hard to swap out repositories > implementations as well as requiring you to have the repository be coupled to > a non-transient class that has metadata. That's why I personally prefer > repositories as services > >> This however makes it impossible to inject say 2 Repositories, which could >> use 2 different Managers, but the service that gets them injected doesn't >> (have to) know about those 2 Managers. > > It is still possible, just very hard and requires some composition trickery > >> In my case I have to inject both Managers explicitly. (Usually I don't >> literally inject 2 Managers, but inject a Manager and a service that uses >> another Manager.) > > An aggregate would be better here, but it causes other trouble, sadly... > >> But I've never seen this as an issue, and I'm curious about a use-case you >> need this for. I can't really think of one (but that doesn't mean those >> cases don't exist). > > Repositories are not necessarily "doctrine" repositories, and in most cases > they shouldn't be. > Your service should not be coupled to > Doctrine\Common\Persistence\ObjectRepository, which is an utility interface > that provides some abstraction for persistence, while your repository > interface should instead abstract "how to find a user by name", for example. > > A typical use case may be a UserRepository: > > class UserRepository implements UserRepositoryInterface > { > public function __construct(ObjectRepository $repo) > { > $this->repo = $repo; > } > > public function getUserByLogin($login) > { > if ($user = $this->repo->findOneBy(['login' => (string) $login])) { > return $user; > } > > if ($user = $this->repo->findOneBy(['email' => (string) $login])) { > return $user; > } > > return null; > } > } > > As you can see, this repository hides away some encapsulation breakages that > are caused by the fact that we assume that the "email" property (note: you > shouldn't know about properties) exists in a user object. > > That's how a repo should look like to me. Injecting D2 repositories > everywhere is pointless - this kind of repository is actually better fitting > your own logic and allows you to decouple yourself from D2 as well. > > Additionally, if you were "pulling" the repo from the object manager, you > would have a hard time in requesting a repo by interface name. > > >> About "the repository is about querying": I agree here in the following >> sense: I use Repositories mainly for read queries, and perform persists and >> flushed outside of Repositories. But when I'm in need of insert, update, etc >> queries (for example batch updates) I put those queries in Repositories to. > > I'd do that only in the ObjectManager mainly to make transactions explicit > > Just ideas, no absolutes, heh. > > > Marco Pivetta > > http://twitter.com/Ocramius > > http://ocramius.github.com/ -- You received this message because you are subscribed to the Google Groups "doctrine-user" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. To post to this group, send email to [email protected]. Visit this group at http://groups.google.com/group/doctrine-user. For more options, visit https://groups.google.com/groups/opt_out.
