Laravel + Doctrine + RepositoryServiceProvider

When we plan our project, we separate our code to different layers, something like:

  • Application layer
    • Domain layer
    • Infrastructure layer

Application layer need to know about both Domain and Infrastructure layers, because if we define interfaces, we need to set-up the implementations in app layer.
In Laravel we can do this in our ServiceProviders, ie. RepositoryServiceProvider

Should look something like this:

ddd_repositories

Repository interfaces living in the Domain layer, but the implementations are living in the Infrastructure layer, since our business logic not interested in how our domain objects are saved or restored.

In Laravel, it’s a little-bit tricky how we resolve the interfaces to implementations, because a Doctrine ORM use a different logic how to repositories are resolved. In Doctrine the the Repository can be resolved from Entity. Let’s see for example a UserEntity looks like this:

/**
* @ORM\Entity(repositoryClass="MyProject\Infrastructure\Repositories\DoctrineUserRepository")
*/
class UserEntity
{

So we link the Repository implementation from the Entity.

In our Service Provider, we need to do the following:

class RepositoryServiceProvider extends ServiceProvider
{
    /**
     * Bootstrap any application services.
     *
     * @return void
     */
    public function boot()
    {
        /** @var EntityManagerInterface $em */
        $em = $this->app->make(EntityManagerInterface::class);

        $this->app->singleton(UserRepository::class, function () use ($em) {
            return $em->getRepository(UserEntity::class);
        });

Now we can inject the repository through IoC.