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.

Reply via email to