Passing Entity Manager to Service Layer ZF Doctrine2 - php

I'm trying to pass the entity manager to a service but havent find a correct way yet. I want to complete remove the em from the controller so thats why I'm finding another way.
I was thinking of this options:
1. I could save it in the registry and then try to access it from the service object. can I access the registry from there?
2. Inject the em to a static variable of a base class for the services in the bootstrap.
What is the correct way yo do it?
thanks

I think generally the best way to do it is to pass the entitymanager as an argument to the constructor.
This allows you to easily replace the entitymanager for example when doing unit tests, and unlike your approaches of 1 and 2, it does not depend on behavior in a base class or global data (the registry is a lot like a global variable)
What you could do to avoid touching the EM in your controllers is using a dependency injection container, such as the one in Symfony2 or the one in ZF2 (not sure if that component is very stable yet).
Another perhaps slightly simpler approach would be to have a sort of a "service locator" object, which you would use in the controller to get instances of your services. You could initialize the locator in your bootstrap with the services, or perhaps with a factory class which creates them.
In any case you will probably require at least some kind of an intermediate object in the controller. Personally I don't really see an issue with simply using the EM itself, unless you have some other reasons besides just not wanting to.

There's nothing wrong, IMO, with letting your controllers know about the EM. I typically use a Zend_Application_Resource to bootstrap Doctrine. That resource facilitates a bootstrap resource called "doctrine" which has an EM available. The abstract controller implements and em() method, which returns the EM.
When instantiating service classes, the constructor simply injects the EM via a call to $this->em() at constructor time.
This is nice, as many times, simple controller actions don't need any special service class, but can instead get away with doing $entity = $this->em()->getRepository('Some\Entity')->find(1); In those cases, I don't see any reason for additional redirection via a service class.

Related

How to use Auryn for DI in the "right" way?

I'm writing a little application from scratch, and I wanted to use some packages from packagist. For DI I choosed Auryn.
Now, one of the first thing that I learnt about Auryn is that it tries to avoid to be a Dependency Container and it is explicitily wrote in the docs that you should not use the instance of Auryn as a container, passing it through the various classes of your app.
I'm fine with that, but, because I have a "main" class as a wrapper for all of the backbone of the app, I think that I should have in the constructor of this main class only the dependency of an Injector object (That's the main Auryin object), then in the constructor of the class I should wire everything to be ready for DI and reflection.
The other way around is to not use a main class, and just use clean procedural code in my index file, wiring all togheter at the same way with Auryn.
What do you advice is the best way to proceed?
The idea behind dependency injection is to gather all the information how your various classes are "wired up" in one place (your DI container class / DI config file), instead of spreading and duplicating it all over your code. I presume your "Main"-class is only instanciated once in your Index.php, so it makes no noticeable difference whether you pass the Auryn instance to Main's constructor or use Auryn to get an instance of Main.

Correct way to log from Entities and Repositories in Symfony2

What is a way to log messages or errors from an Entity or Repository class in the symfony2 architecture? In symfony1 you could use the singleton to kill puppies by doing something like this to get the logger from anywhere:
sfContext::getInstance()->getLogger()
Symfony2's container model is stricter, which is great, but how should one go about logging from non-container-aware classes? For repos, I guess you can define them (all) as services, with a dependency on the logger, and go from there. But what about when you just have an instance of an Entity class?
Historically I'd want to put the log message inside class methods, but now? Should I pass the logger (as a parameter) into every class method that wants to write a log message? This seems like a bit of overkill but perhaps it's best practice?
Or am I looking at this wrong and Entities or Repos shouldn't be writing log messages but passing them back to the controller to handle?
You should probably avoid putting business logic (even logging) inside entity model.
As for the repositories, the way you described is the right one.

How to access services inside non-controller function in Symfony 2

You may access the (let's say) Doctrine service inside the controller, using:
$d = $this->getDoctrine()
now I want my controller to call another function (in another class) and I want that class to have access to all services. Is that possible without passing the services as variable?
You have to inject dependent services to your class or method. If you were thinking about some global object you might access everywhere than it's not the right way to go (and you can't actually access the container this way). You'd miss the whole point of dependency injection.
You can inject the services to your class two ways:
Manually
Let DIC do it
First solution requires you to pass the dependency yourself either way (constructor, setter, method).
The later solution means you define your class as a service and let container construct it and inject the dependencies. It can only be done if you can delegate object creation to DIC. It cannot be done with Entities for example.
Be careful with injecting whole container. It's not the best practice. You'd introduce dependency on a whole container which might have different services depending on the configuration. Dependencies wouldn't be clear.

How to access my singletons without using global state?

I know that Singleton pattern is bad because it uses global state. But in most applications, you need to have a single instance of a class, like a database connection.
So I designed my Database object without using the singleton pattern but I instanciate it only once.
My question is, how can I access my object in the low level classes (deep in the object graph) without passing it all over the place?
Let's say I have an application controller which instanciates (ask a factory to instanciate it actually) a page controller which instaciates a User model which requires the database object.
Neither my app controller nor my page controller need to know about the database object but the User class does. How am I suppose to pass the object to it?
Thanks for your time!
Consider using a global container:
You register the objects that are indeed relevant to the several subsystems of the application.
You then request that container those objects.
This approach is very popular in dependency injection frameworks (see Symfony DI, Yadif).
Singleton is bad, no doubt about it.
In the case you describe, the database object is an implementation detail of the User object. The layers above need only know about the User, not the database object.
This becomes much more apparent if you hide the user object behind an interface and only consume that interface from the layers above.
So the page controller should deal only with the interface, not the concrete class that depends on the database object, but how does in create new instances? It uses an injected Abstract Factory to create instances of the interface. It can deal with any implementation of that interface, not only the one that relies on a database object.
Once more, you hide the page controller behind an interface. This means that the concrete implementation's reliance on the Abstract Factory becomes another implementation detail. The Application Controller only consumes the page controller interface.
You can keep wrapping objects like that like without ever needing to pass around instances. Only in the Composition Root do you need to wire all dependencies together.
See here for a related answer with examples in C#: Is it better to create a singleton to access unity container or pass it through the application?
The way I've always accomplished this is to implement a static getInstance function that will return a reference to the single instance of that class. As long as you make sure that the only way you access the object is through that method, you can still ensure that you only have one instance of the singleton. For example:
class deeply_nested_class {
public function some_function() {
$singleton = Singleton::getInstance();
}
}
There are two main objects involved in loading/saving a user using the database: the user and the repository.
You seem to have implemented the functionality on the User, but I think it belongs on the Repository. You should pass the user to the Repository to save it.
But, how do you get hold of the Repository? This is created once at the top level and passed into services that need it.
The construction dependency graph and the call dependency graph are not the same thing.
Given the example you outlined, you are almost there. You are already using a factory to instantiate your page controller, but your page controller is instantiating the users directly and as your User needs to know the database.
What you want to do is use a factory to instantiate your User objects. That way the factory can know about the database and can create User instances which know about it too. You will probably be better off making interfaces for all the dependencies, which will help with testing and will mean your code is nicely decoupled.
Create an IUserFactory which creates IUser implementations and pass this into your PageControllerFactory, then your ApplicationController only needs to know about the PageControllerFactory, it doesn't need to know anything about the IUserFactory or the database.
Then in your application start up you can create all of your dependencies and inject them in to each other through the constructors.

ServiceLocator and the Open/Closed Principle

I'd like to:
Make commonly required services visible to all classes that need them,
with a minimum of boilerplate, and
without sacrificing testability!
It's a small project and I think DI might be overkill, but maybe I'm wrong? Anyhow, I have been focusing on the ServiceLocator pattern as described by Martin Fowler
In a client class' constructor, I have something like this:
this->db = Locator::getDb();
this->log = Locator::getLogger();
Then the rest of the class' methods access the service through those member attributes, e.g.:
this->fooModel = new fooModel(this->db);
fooItem1234 = this->fooModel->findById(1234);
However I would also like this level of visibility for "model" objects (like fooModel above) because they are accessed from several different places and there is no need to have more than one instance.
So my initial thought was to extend Locator to have a ::getFooModel() but now it seems I'm violating the Open/Closed Principle, since I'll have to modify Locator every time I introduce a new model class.
To satisfy OCP, I could use the Dynamic Service Locator (also described on Fowler's page) however I'm not totally sold on this for the same reasons as him, i.e. it's not explicit enough.
Another solution would be to just make all my models' methods static. So:
fooItem1234 = FooModel::findById(1234);
I like this because it's zero boilerplate. I can just create a new model class and start calling it from anywhere with a single line. But now the model depends on Locator to find its DB connection and I'm not sure how I feel about that. For one, if I ever needed to have two fooModels open on separate database connections, it would be a mess and/or impossible. That said, I don't actually need to do that currently so this option seems a little tempting.
Finally, there's DI. But like I said above I think it might be too much for this little project.
Conclusion: I'm a little stuck here and would appreciate some advice from the gurus of StackOverflow!
Why do you think that DI is overkill for your project? DI patterns such as Constructor Injection is way simpler and cleaner than Service Locator (which I consider an anti-pattern).
I consider Service Locator to be an anti-pattern since it is totally opaque to the user of the API which dependencies need to be in place; thus, one could easily invoke methods on your objects in a context where the Service Locator would throw, and the API gives you absolutely no clue that this is the case.
You don't need a DI Container to use DI. If just have a simple project, you can use what is known as Poor Man's DI where you wire up dependencies manually.
... and there is no need to have more than one instance.
You're mixing apples and oranges. The fact that you only need one instance of a class for an application, is not the same thing as it being a good idea to make that instance globally available. With DI you don't change the cardinality - there is still just one instance. What you change is the scope of variables that address said instance. There's a difference.

Categories