Reputation:
As I've learned the hard way, entities should not store any real logic since their usage is to store data.
Also, I've read that Controllers shouldn't have any "real code" but only set a few values if needed and point them to services which are actually used to do work. (Trimming fat from controllers).
I understand the points and even though I'm a newbie with Symfony I know that classes with code "for all and everything" just are terribly bad practice (and Controllers throughout the Symfony Book and Symfony Cookbook really to look like that). Easy to create, impossible to maintain. And if you get into situation where you have to decouple your code you're in for a whole lot of fun. But I get it, since these books are aimed at newcomers primarily.
So, how do I actually create Entity Type Managers. Are they the way to go at all?
Say I have an Image entity. I need ImageManager to delete, update, call thumbnail service to create thumbnails etc. Where is it's place? Where does it belong in Directory Structure at all? It can't be an unmapped entity since it needs services injected into it.
Best Practices cookbook article doesn't mention anything like this .
Upvotes: 5
Views: 1200
Reputation: 2131
You might take a look at the way FOSUserBundle structures its code.
It has a UserManager in FOSUserBundle/Model
which does things that don't require any knowledge of the storage of User entities and another UserManager in FOSUserBundle/Doctrine
which extends the former and which does things that do require knowledge of the storage layer (it gets injected with an EntityManager, for example). The FOSUserBundle/Doctrine/UserManager
is defined as the service which may be called from controllers.
The nice thing about this structure is that it makes testing very easy. Unit tests for FOSUserBundle/Model/UserManager
are very lightweight and don't require mocks of the doctrine stuff. The Unit tests for FOSUserBundle/Doctrine/UserManager
are the place where doctrine stuff is mocked.
Upvotes: 1
Reputation: 4148
I'm not aware that there is a best practice for this kind of thing, but when I do this I always place my managers in a Path\To\MyBundle\Manager
namespace. The only example I could find within my project of a third party vendor that does the same thing is the ElasticaBundle.
The key thing is that you define your manager as a service and inject the dependencies that you need. Try and make your manager dependent on interfaces as opposed to actual classes in order to make it easier to test and to make it easier to swap out individual components later on if necessary.
It's also a very good idea to make your manager implement an interface that defines all of it's public methods, as the RepositoryManager
class does in the ElasticaBundle I linked to above.
Upvotes: 0