Dependency Injection of Repository Interface for a Domain Specification Object - php

not sure if I'm just too tired and missing something so apologies in advance.
I have a php domain which I need to restructure because ended having an anemic model using services. This is because I'm not using Doctrine but Eloquent by Laravel as my mapper (reasons are due to linking to other different DB server types)
My reviewed structure needs to be something similar to do this: ( I'm only including a couple of things for this example)
Template Entity has TemplateName as VO.
The TemplateName must satisfy 2 specs. Has to be more than 3 chars long and has to be unique.
I am using a TemplateRepositoryInterface to check the uniqueness and the interface has an Eloquent implementation bounded in a service provider.
Therefore the Template Entity has a method:
public function create()
{
if ($this->meetsTemplateNameSpecification())
{
//fire events etc... saving to repo is done one step above from a service that call this class and gets $this to send tot he interface
return $this;
}
throw new InvalidArgumentException("Template name is not valid.");
}
Then my meetsTemplateNameSpecification method:
private function meetsTemplateNameSpecification($originalTemplateName = null)
{
$templateNameSpecification = new TemplateNameSpecification($this->name, $originalTemplateName);
if($templateNameSpecification->isMet())
{
return true;
}
return false;
}
Before this restructure, a service was initiating all these and passing the RepositoryInterface to them so that was easy. However, this way I don't know how and /or where to pass or inject the interface because if I have it injected from the container to the Specification class then I cannot initiate from the Entity and I cannot inject the Spec class to the entity either because i want to be able to use it's constructor.
I find it very hard to do in PHP and Active Record with keeping a separation of concerns and not having a dependency on persistence in the domain.
Does anyone have a better structure? Let me know if you need more code please.
So far the only solution that comes to mind is to have static methods in my specification objects so that they do not need to be initiated and I can inject the Repo dependency from the container. Is this the way to go or there's better ways that work with PHP. I hate having to inject from the container to the Domain too but don't think there's any better way unless you're using a different architecture.

I think you're overcomplicating things.
Specification pattern is cool if used in a very general method signature that takes specifications as parameters, or if you have a whole family of specifications. With just one or two particular conditions to test, it might be overkill.
Also, trying to inject a Repository into a domain object (as I guess you are) may be causing you more trouble than good. String length is most probably not a domain rule and uniqueness may not be either. You might be better off checking those constraints at the Application Service (or Controller) level, directly calling the Repository there for uniqueness, which will spare you all the injection trouble.

Related

Dependencies - Injection vs new Instances

I'm currently using Laravel and have a pretty good general grasp now on how the dependency injection and service container works now. I see it working very well when programming to interfaces, but what about concrete classes?
I utilize a service layer between my controllers and models. The point of the service objects was so that I could easily reuse their methods elsewhere, like in a different controller. But there are cases where I also need to use a service inside another service.
So I've been using the constructor for the dependency injection inside my services. The issue I kind of see is that sometimes I only need a service (inside one of my other services) for 1 method. So doing it in the constructor makes it rather large. On the other hand, since I've been setting these parameters in the constructor, I can't simply new-up an instance on demand, since it requires those parameters. For example, let's say I have an OrderService class, and for the constructor, I see two ways I can go about it:
public function __construct(FileUploadService $fileUploadService)
{
$this->fileUploadService = $fileUploadService;
}
or
public function __construct()
{
$this->fileUploadService = new FileUploadService;
}
I've mostly been doing it the first way, but have been thinking about the second. If I ever needed this OrderService somewhere else in the app, I can't simply create a new instance since it relies on the FileUploadService, unless I create a new instance of that too. But you can see that it will start to cascade without the dependency injection, because what if the FileUploadService depends on something also? It's just easier to resolve it out of the container.
Maybe there's something I'm missing, because it almost feels like a catch 22 in some ways. I'd like to note that a majority of these classes I'm injecting are concrete classes, so I don't need to swap them out at any particular point.
I've thought about just creating a new instance in the constructors for each service I need, that way I can also new-up the instance without providing parameters. But I like to follow best practices, so I was wondering what other experienced developers thought about this.

symfony2.3 performance tips on service, controller, controller as service

What are the main differences, in term of performance between service, controller as a service or using a sort of auxiliary object to do the job?
more precisely for this scenario/use-case:
i've got an API on mysite/api, my question is:
Is it better to define a controller as service, a service itself or using in "classical way" as a controller doing all the job with at least an auxiliary object (as a mini-lib) to do most of the job?
auxiliary object I mean use an istance of a class, i suppose everytime the api is called, create the new object (not so good for performance I think).
thanks in advice for your answers.
There won't be any significant performance differences, and all three approaches are absolutely valid, it just matters on your use case.
Thing to note: Controllers are basically services, they are just container aware by default in Symfony (making them Service Locators). It doesn't matter whether controller is a Service, a ContainerAwareInterface object or some object you made, it has to be instantiated either way.
That said, controller is just one of probably hundreds (if not thousands) of objects that will be created on each request and time needed to instantiate it is really negligible.
Use whatever method suits you best.
Edit
Hell, symfony controllers aren't even ContainerAware by default, they are just made so in their examples since they always extendsSymfony\Bundle\FrameworkBundle\Controller\Controller. You can try to make a Controller class like so:
<?php
namespace MyVendor\MyBundle\Controller;
class MyCustomController
{
public function myAction()
{
// do your thing here
}
}
And it will work just fine.
Here is the Symfony code that instantiates controller: ControllerResolver::createController
Basically, it checks whether string matches 'Bundle' pattern or 'Service' pattern. If neither, it just treats it as 'ClassName::methodName', and one way or another: instantiates it.
There is no difference which approach to use. But there are a lot of another questions - rest api routing, formats, documentation etc.
Use ready solution for rest-api gimler/symfony-rest-edition

Domain driven design, entity lazy loading

I am fairly new to Domain Driven Design (DDD), but what I understand of it is that you speak to the application service, which is the entry to your "model". The service can talk to a repository which uses sources (files, databases, etc) to get data. The repository returns an entity.
That is the global idea what I get of it. The service knows the repository but not the entity etc.
Now I have the following issue.
I have an entity user, which is something like the following (is just an example)
<?php
class User
{
protected $name;
protected $city_id;
public function getCity()
{
// return $city_entity;
}
}
The getCity() function returns the city entity. I wish for this function to use lazy loading so injecting the CityEntity when you use the user repository is not really lazy loading.
I came with two solutions to the problem. But I feel that both are against the DDD principals.
First solution I came up with is to inject the city repository in the user entity, which has disadvantages: if you need more repositories you have to load them all in the entity. It looks like answer but it just looks like a wrapper for the repository to me. So why not just inject the repository then?
Second solution, you give the entity a service locator. The disadvantage of this is you don't know any more which repositories are needed unless you read the code.
So now, the question is, what is the best way to give the flexibility of lazy loading while keeping the DDD principals intact?
One of main point in DDD is that your domain model should only express the ubiquitous language of the bounded context to handle the business rules.
Thus, in DDD entities, lazy loading is an anti-pattern. There are some reasons for that:
if an aggregate holds only the data that it requires to ensure business invariants, it needs them all and they are few, thus eager loading works better.
if you lazy load data, your clients have to handle much more exceptional paths that those relevant in business terms
you can use shared identifiers to cope with references between aggregates
it's cheap to use dedicated queries for projective purposes (often called read-model)
IMHO, you should never use DDD entities as a data access technique: use DTOs for that.
For further info you could take a look at Effective Aggregate Design by Vaughn Vernon.

Passing Entity Manager to Service Layer ZF Doctrine2

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.

Composing a Controller class with Dependency Injection in PHP

How to solve the problem of composing a Controller class in PHP, which should be:
easily testable by employing Dependency Injection,
provide shared objects for end programmer
provide a way to load new user libraries
Look down, for controller instantiation with a Dependency injection framework
The problem is, that derived Controllers may use whatever resources the programmer wants to (eg. the framework provides). How to create a unified access to shared resources (DB, User, Storage, Cache, Helpers), user defined Classes or another libraries?
Elegant solution?
There are several possible solutions to my problem, but neither one looks to be a elegant
Try to pass all shared objects by constructor? (may create constructor even with 10 placeholders)
Create getters, settters? (bloated code) $controller->setApplication($app)
Apply singletons on shared resources? User::getInstance() or Database::getInstance()
Use Dependency Injection container as a singleton for object sharing inside the controller?
provide one global application singleton as a factory? (this one looks very used in php frameworks, hovewer it goes strongly against DI principles and Demeter's law)
I understand, that creating strongly coupled classes is discouraged and banished for :), however I don't know how this paradigm applies to a starting point for other programmers (a Controller class), in which they should be able to access shared resources provided to the MVC architecture. I believe, that breaking up the controller class into smaller classes would somehow destroy the practical meaning of MVC.
Dependency Injection Framework
DI Framework looks like a viable choice. However the problem still persists. A class like Controller does not reside in the Application layer, but in the RequestHandler/Response layer.
How should this layer instantiate the controller?
pass the DI injector into this layer?
DI Framework as a singleton?
put isolated DI framework config only for this layer and create separate DI injector instance?
Are you developing a framework yourself? If not, your question does not apply, because you have to choose from already existing frameworks and their existing solutions. In this case your question must be reformulated like "how do I do unit testing/dependency injection in framework X".
If you are developing a framework on you own, you should check first how already existing ones approach this issue. And you must also elaborate your own requirements, and then just go with the simplest possible solution. Without requirements, your question is purely aesthetic and argumentative.
In my humble opinion the simplest solution is to have public properties which initialize to defaults provided by your framework, otherwise you can inject your mocks here. (This equals to your getters/setters solution, but without the mentioned bloat. You do not always need getters and setters.) Optionally, if you really need it, you may provide a constructor to initialize those in one call (as you suggested).
Singletons are an elegant solution, but again, you must ask yourself, is it applicable in your case? If you have to have different instances of the same type of object in your application, you can't go with it (e.g. if you wish to mock a class only in half of your app).
Of course it is really awesome to have all the options. You can have getters/setter, constructors, and when initialization is omitted, default are taken from a singleton factory. But having too many options when not needed, is not awesome, it is disturbing as the programmer has to figure out which convention, option and pattern to use. I definitely do not want to make dozens of design decisions just to get a simple CRUD running.
If you look at other frameworks you will see that there is no silver bullet. Often a single framework utilizes different techniques depending on the context. In controllers, DI is a really straightforward thing, look at CakePHP's $helpers, $components variables, which instruct to inject appropriate variables into the controller class. For the application itself a singleton is still a good thing, as there is always just a single application. Properties less often changed/mocked are injected utilizing public properties.
In case of an MVC, subclassing is perfectly viable option as well: just as AppController, AppView, AppModel in CakePHP. They are inserted into the class hierarchy between the frameworks's and all your particular Controller, View and Model classes. This way you have a single point to declare globals for your main type of classes.
In Java, because of dynamic class loaders and reflection, you have even much more options to choose from. But on the other hand, you have to support much more requirements as well: parallel requests, shared objects and states between worker threads, distributed app servers etc.
You can only answer the question what is right for you, if you know what you need in the first place. But actually, why do you write just another new framework anyway?
Singletons are frowned upon when Dependency Injection is viable (and I have yet to find a case where a Singleton was necessary).
More than likely you will have control of instantiation of controllers, so you can get away with the mentioned $controller->setApplication($application), but if necessary you can use static methods and variables (which are far less harmful to the orthogonality of an application than Singletons); namely Controller::setApplication(), and access the static variables through the instance methods.
eg:
// defining the Application within the controller -- more than likely in the bootstrap
$application = new Application();
Controller::setApplication($application);
// somewhere within the Controller class definition
public function setContentType($contentType)
{
self::$application->setContentType($contentType);
}
I have made of a habit of separating static and instance properties and methods (where necessary, and still grouping properties at the top of the class definition). I feel that this is less unwieldy than having Singletons, as the classes still remain quite compact.
How about refactoring?
Granted that was not one of your options, but you state the code is a largely coupled class. Why not take this time and effort to refactor it to more modular, testable components?
As far as I understand, the Application class of yours should be the dispatcher. If so, I would rather use the controller constructor to pass an instance of the Application, so the controller would know who's invoking it. At later point if you want to have a different Application instance depending on whether the code is invoked from within CLI, you can have an ApplicationInterface which the Application\Http and Application\Cli would implement and everything would be easy to maintain.
You could also implement some factory pattern to get a nice implementation of the DI. For example, check the createThroughReflection method here: https://github.com/troelskn/bucket/blob/master/lib/bucket.inc.php
I hope this makes sense.
Regards,
Nick
You could also use a ControllerFatory in which you would give to your Application or Router/Dispatcher
Sou you could call $controllerFactory->createController($name);
Your Application would have no idea how to create your controllers the Factory would. Since you ca inject your own ControllerFactory in to your DI container you can manage all dependencies you want depending on the controller.
class ControllerFactory {
public function __construct(EvenDispatcher $dispatcher,
Request $request,
ResponseFactory $responseFactory,
ModelFactory $modelFactory,
FormFactory $formFactory) {
...
}
public function createController($name = 'Default') {
switch ($name) {
case 'User':
return new UserController($dispatcher,
$request,
$responseFactory->createResponse('Html'),
$modelFactory->createModel('User'),
$formFactory->createForm('User'),...);
break;
case 'Ajax':
return new AjaxController($dispatcher,
$request,
$responseFactory->createResponse('Json'),
$modelFactory->createModel('User'));
break;
default:
return new DefaultController($dispatcher, $request, $responseFactory->createResponse('Html'));
}
}
}
So you just need to add this factory in your DI container and pass it to your Application.
Whenever you need a new controller you add it to the factory and if new dependencies are required you give them to the factory through your DI container.
class App {
public function __construct(Router $router,Request $request, ControllerFactory $cf, ... ) {
...
}
public function execute() {
$controllerName = $this->router->getMatchedController();
$actionName $this->router->getMatchedAction();
$controller = $cf->createController($controllerName);
if(is_callable($controller, $actionName)) {
$response = $controller->$action(request);
$response->send();
}
}
}
This is not production code, I haven't tested, but this is how you decouple your controllers from your application. Notice here though that there is one bad coupling here because my controller return's a response and I execute the response in the App. But like I said this is just a small example.
It is usually a good idea to pass factories for Models, Forms, and Controllers to their respective parents, because you will end up loading all your object Graph at bootstrap time wich is really bad and memory consuming.
I know this answer was already approved, but it's my 2 cents on the subject
There is a good article on the subject
http://miller.limethinking.co.uk/2011/07/07/dependency-injection-moving-from-basics-to-container/

Categories