docteurklein/repository-service-bundle
Installation
composer require docteurklein/repository-service-bundle
Register the Bundle
Add the bundle to your AppKernel.php (or config/bundles.php for Symfony Flex):
new \DocteurKlein\RepositoryServiceBundle\DocteurKleinRepositoryServiceBundle(),
First Use Case
Create a custom repository class (e.g., src/Repository/ProductRepository.php):
namespace App\Repository;
use Doctrine\ORM\EntityRepository;
/**
* @Service("app.product_repository")
* @Tag("repository", attributes={"for"="App\Entity\Product"})
*/
class ProductRepository extends EntityRepository
{
// Custom methods here
}
Inject it via dependency injection:
class ProductService
{
public function __construct(
private ProductRepository $productRepository
) {}
}
Automatic Service Registration
The bundle auto-registers repositories as services under the name repo.{entity_namespace} (e.g., repo.app_product).
Example: Inject repo.app_product directly if no alias is defined.
Custom Repository Aliases
Use the @Service and @Tag annotations to define aliases (e.g., products in the README).
/**
* @Service("products")
* @Tag("repository", attributes={"for"="App\Entity\Product"})
*/
class ProductRepository extends EntityRepository {}
Now inject products instead of the full service name.
Default Repository Fallback
If no custom repository is tagged, the bundle falls back to the default EntityRepository.
Override only when needed.
ManagerRegistry Integration
The bundle uses ManagerRegistry internally, so repositories work across multiple entity managers if configured.
Entity-Centric Development
UserRepository, OrderRepository).Service Layer Abstraction Use repository aliases in services/controllers to decouple business logic from Doctrine specifics:
class ProductService {
public function __construct(private ProductRepository $repository) {}
}
Testing
Mock repositories by type-hinting the interface (EntityRepository) or alias:
$this->container->set('products', $mockRepository);
config/bundles.php.Missing JMSDiExtraBundle
Without jms/di-extra-bundle, the @Service and @Tag annotations won’t work. Install it first:
composer require jms/di-extra-bundle
Entity Namespace Mismatches
The for attribute in @Tag must match the entity’s FQCN exactly (including namespace).
❌ Wrong: for="Product" (missing namespace)
✅ Correct: for="App\Entity\Product"
Circular Dependencies
Avoid injecting repositories into other repositories (e.g., UserRepository injecting ProductRepository). Use services instead.
Bundle Order Matters
Register DocteurKleinRepositoryServiceBundle after DoctrineBundle in AppKernel.php to ensure Doctrine is initialized first.
No Dynamic Updates Changes to repository classes require a cache clear:
php bin/console cache:clear
Service Not Found? Check if the repository is tagged correctly and the entity exists in the default entity manager. Run:
php bin/console debug:container | grep repo
Alias Not Working?
Verify the @Service annotation’s ID matches the alias you’re injecting.
Doctrine Configuration Issues
Ensure the custom repository class is listed in doctrine.orm.entity_managers.default.mapping_types if using non-standard mappings.
Multiple Entity Managers
The bundle only registers repositories for the default entity manager. For custom managers, configure manually in services.yaml:
services:
repo.custom_manager.product:
class: App\Repository\ProductRepository
factory: ['@doctrine.orm.entity_manager', getRepository]
arguments: ['App\Entity\Product']
Override Default Repositories
To replace the default EntityRepository for an entity, tag your custom repository with the same for attribute.
Custom Service Names
Override the default service name pattern (repo.{entity_namespace}) by implementing a compiler pass:
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
Additional Tags
Extend the bundle’s logic by adding custom tags (e.g., @Tag("repository", attributes={"priority"=10})) and handle them in a compiler pass.
Non-Doctrine Repositories While designed for Doctrine ORM, you could adapt the bundle for other storage systems (e.g., MongoDB) by modifying the service factory logic.
How can I help you explore Laravel packages today?