Organize business logic in Symfony2 - symfony

I'm converting a Symfony1 application to Symfony2, and I'm trying to follow Symfony2's best practices.
I have a problem with the business logic: In the old app, all the logic was in the controller (very fat controllers). I've moved it to entity repositories, but I'm not sure if this is the correct way (because, aside other things, I need to send emails, and this isn't working).
For example, the save function for a resource reservation manager (calendar) is:
Begin transaction
Validate that the given resource isn't used in the time-lapse I'm trying to save
If the data is correct and the resource is marked as "mandatory confirmation", an email is sent to all the users from the "confirmers" group
An email is sent to the current user telling him that the resource has been reserved correctly (and, if needed, telling that a "confirmer" must approve his reservation)
If all has worked well, commit the transaction. If any error has happened, rollback the transaction
As you can see, there is lots of business logic (this example is one of the easier modules), using multiple kind of entities, users, emailers, etc. So, how can I organize it? Should I put the business logic in an entity repository, or is better to use services? And for the emails, maybe it's better to send them from an event listener? And do you know where can I find some examples about this?

Simply make services to handle these tasks. For example; create a service that you can re-use, that's testable, for sending emails. Make the API as simple as it can be, and then you can use it in your controller.
The way I think about it is that the controller is ONLY there to send information around various services, and to handle what is output to the user. Anything else should be controlled via services, and the responses from those services.
It's not a bad thing to have small classes - your classes should aim to do one thing, and one thing well. If you split them up enough then they'll be easily testable, and easily reusable.
The Symfony Books are excellent resources for this kind of thing:
http://symfony.com/doc/current/book/service_container.html

You might find this article of Martin Fowler's useful. He says…
In general, the more behavior you find in the services, the more likely
you are to be robbing yourself of the benefits of a domain model. If all your logic is in services, you've robbed yourself blind.
I suspect he and Eric Evans would implement your business logic using a DDD approach along the lines of…
class Resource
{
public function isUsedIn(TimePeriod $tp);
public function isMandatoryConfirmation();
}
class ReservationManager
{
public function save(Resource $r, TimePeriod $tp)
{
if (! $r->isUsedIn($tp) || $r->isMandatoryConfirmation()) {
// send email to all the users from the "confirmers" group
// send email to the current user
}
}
}
Unfortunately in my experience with Symfony2, this hasn't been done and the code has ended up inside services. Symfony acknowledge that business logic can be put into Doctrine entities but from my point of view, it is a bit of weasel offer.
Services are container aware and as such can easily access other services to perform other functions like sending emails, logging messages. Doctrine entries cannot access other services which means that like Seer, in our project, we end up using services.
If you like the idea of moving more of your business out from services, it isn't difficult however Doctrine & Symfony do not seem to support it out of the box :-(

Related

Unity - Use concrete type depending on user choice

I have a small app (Win Forms) where I have two different repositories (SQL Server and Redis) both implementing a interface IFilterRepo.
I also have a service class that depends on the IFilterRepo. The client (the Win Form) call the service to access filter data.
I want the client to have two radio buttons where a user can choose which repo to use. And here comes my dilemma. How should I tell the service which concrete class to instantiate as IFilterRepo? I mean, ALL Unity registrations and references to it shall be done in the composition root. Is that "rule" really possible in this case?
This is a common question, and the answer is generally to use an Abstract Factory.
Here is a good article on the subject (I link this all the time, but I didn't write it):
http://blog.ploeh.dk/2012/03/15/ImplementinganAbstractFactory/
As noted in the article, you can make the factory part of the composition root, so that calling container.Resolve() inside the factory doesn't violate that rule.
Edit
You would register different implementations of the service using a name (string):
http://msdn.microsoft.com/en-us/library/ff648211.aspx
myContainer.RegisterType<IMyService, CustomerService>("Customers");
And then your factory would resolve by that name:
public IFilterRepo Create(string myName)
{
return myContainer.Resolve<IFilterRepo>(myName);
}
Edit 2
The question you asked in your last comment is a bit much to answer here, but in brief: your factory itself would implement an interface, and would be resolved and registered via the container.
As a general matter, I would not recommend accessing a repository directly from the code behind--I would at least look at having a layered architecture (or better, an Onion architecture, which works very well with DI).
Finally, I have not done WinForms development in years, but I don't think it fits perfectly with using a container/Composition Root, since you don't have full control over the lifecycle of your objects (you can't inject services into your form constructors). The same is true of ASP.Net Webforms. So you may have to use property injection for your factory and other services needed in your form, or just resolve the factory directly via calling a static instance of the container (container.Resolve()). This is imperfect, and goes against the idea of having a Composition Root, and more toward service location.
You might google keywords "Unity WinForms" and/or "[OtherDIFramework] Winforms" to get some ideas of how to structure your code.

Understanding Symfony2 services

I'm quite new to Symfony 2 and I'm moving to advanced topics like services. When should an object be a service?
For example, say that you have a facade object for making a call to a REST service. This class needs a username and password. Would it be correct modeling that class as a global service? Even if it's used only in a portion of the whole project?
# app/config/config.yml
parameters:
my_proxy.username: username
my_proxy.password: password
services:
my_proxy:
class: Acme\TestBundle\MyProxy
arguments: [%my_proxy.username%, %my_proxy.password%]
Definition taken from the Symfony2 glossary:
A Service is a generic term for any PHP object that performs a specific task. A service is usually used "globally", such as a database connection object or an object that delivers email messages. In Symfony2, services are often configured and retrieved from the service container. An application that has many decoupled services is said to follow a service-oriented architecture.
I think your example is a perfect candidate for a service.
You don't want to copy construction code to all places you need your API client. It's better to delegate this task to the dependency injection container.
This way it's easier to maintain (as construction happens in one place and it's configurable).
It's also more flexible as you can easily change the API client class without affecting code which uses it (as long as it implements the same interface).
I don't think there's a golden rule. But basically all classes implementing a task are good candidates for a service. Entities on the other hand are not as they're most often just data holders.
I always recommend Fabien's series of articles on the subject: http://fabien.potencier.org/article/11/what-is-dependency-injection
Yes, because this will spare you the configuration part. You're not going to fetch the username and password and give it to the constructor each time you need this class.

How to access 'templating' service not in controller

Ok, so the problem is:
I've got some 'order' entity, and it has 'status' property. On changing status, i wanted some other objects to be informed of this event, so i've decided to use Observer pattern. One of the observers notifies clients via email. Now i want to render Email text's from some of the twig templates. As i get from the Book, rendering templates in controllers are done with 'templating' service.
So the question as it follows: How can i access 'templating' service in my Observer class?
Specification:
I was advised, to implement my Observer as a service, but i'm not sure 'bout that. I've tried to solve this problem, and here is my options:
Use Registry. Solution that is straight and hard as rail. I guess it misses the whole point of DI and Service Container. Huge plus of this solution, is that i can access all common services from any point of my application.
To pass needed services from the context via constructor, or via setters. This is more like in Sf2 spirit. There comes another list of problems, which are not related to this question field.
Use observers as a service. I'm not really sure 'bout this option 'cos, in the book it is written, that service is a common functionality, and i don't think that observing entity with number of discrete properties is a common task.
I'm looking for a Sf2 spirit solution, which will be spread over whole project, so all answers with an explanation are appreciated.
As with any other service in a Symfony2 project, you can access it from within other classes through the dependency injector container. Basically what you would do is register your observer class as a service, and then inject the templating service into your observer service. See the docs for injecting services.
If you're not familiar with how Symfony handles dependency injection, I'd suggest reading that entire chapter of the documentation - it's very helpful. Also, if you want to find all the services that are registered for application, you can use the console command container:debug. You can also append a service name after that to see detailed info about the service.
Edit
I read your changes to the question, but still recommend going down the DI route. That is the Symfony2 spirit :) You're worried that your observer isn't common enough to be used as a service, but there's no hard rule saying "You must use this piece of code in X locations in order for it to be 'common'".
Using the DIC comes with another huge benefit - it handles other dependencies for you. Let's say the templating service has 3 services injected into itself. When using the DIC, you don't need to worry about the templating service's dependencies - they are handled for you. All you care about is telling it "inject the templating service into this other service" and Symfony takes care of all the heavy lifting.
If you're really opposed to defining your observer as a service, you can use constructor or setter injection as long as you're within a container-aware context.

The Purpose of a Service Layer and ASP.NET MVC 2

In an effort to understand MVC 2 and attempt to get my company to adopt it as a viable platform for future development, I have been doing a lot of reading lately. Having worked with ASP.NET pretty exclusively for the past few years, I had some catching up to do.
Currently, I understand the repository pattern, models, controllers, data annotations, etc. But there is one thing that is keeping me from completely understanding enough to start work on a reference application.
The first is the Service Layer Pattern. I have read many blog posts and questions here on Stack Overflow, but I still don't completely understand the purpose of this pattern. I watched the entire video series at MVCCentral on the Golf Tracker Application and also looked at the demo code he posted and it looks to me like the service layer is just another wrapper around the repository pattern that doesn't perform any work at all.
I also read this post: http://www.asp.net/Learn/mvc/tutorial-38-cs.aspx and it seemed to somewhat answer my question, however, if you are using data annotations to perform your validation, this seems unnecessary.
I have looked for demonstrations, posts, etc. but I can't seem to find anything that simply explains the pattern and gives me compelling evidence to use it.
Can someone please provide me with a 2nd grade (ok, maybe 5th grade) reason to use this pattern, what I would lose if I don't, and what I gain if I do?
In a MVC pattern you have responsibilities separated between the 3 players: Model, View and Controller.
The Model is responsible for doing the business stuff, the View presents the results of the business (providing also input to the business from the user) while the Controller acts like the glue between the Model and the View, separating the inner workings of each from the other.
The Model is usually backed up by a database so you have some DAOs accessing that. Your business does some...well... business and stores or retrieves data in/from the database.
But who coordinates the DAOs? The Controller? No! The Model should.
Enter the Service layer. The Service layer will provide high service to the controller and will manage other (lower level) players (DAOs, other services etc) behind the scenes. It contains the business logic of your app.
What happens if you don't use it?
You will have to put the business logic somewhere and the victim is usually the controller.
If the controller is web centric it will have to receive its input and provide response as HTTP requests, responses. But what if I want to call my app (and get access to the business it provides) from a Windows application which communicates with RPC or some other thing? What then?
Well, you will have to rewrite the controller and make the logic client agnostic. But with the Service layer you already have that. Yyou don't need to rewrite things.
The service layer provides communication with DTOs which are not tied to a specific controller implementation. If the controller (no matter what type of controller) provides the appropriate data (no mater the source) your service layer will do its thing providing a service to the caller and hiding the caller from all responsibilities of the business logic involved.
I have to say I agree with dpb with the above, the wrapper i.e. Service Layer is reusable, mockable, I am currently in the process of including this layer inside my app... here are some of the issues/ requirements I am pondering over (very quickly :p ) that could be off help to youeself...
1. Multiple portals (e.g. Bloggers portal, client portal, internal portal) which will be needed to be accessed by many different users. They all must be separate ASP.NET MVC Applications (an important requirement)
2. Within the apps themselves some calls to the database will be similar, the methods and the way the data is handled from the Repository layer. Without doubt some controllers from each module/ portal will make exactly or an overloaded version of the same call, hence a possible need for a service layer (code to interfaces) which I will then compile in a separate class project.
3.If I create a separate class project for my service layer I may need to do the same for the Data Layer or combine it with the Service Layer and keep the model away from the Web project itself. At least this way as my project grows I can throw out the data access layer (i.e. LinqToSql -> NHibernate), or a team member can without working on any code in any other project. The downside could be they could blow everything up lol...

Creating good interfaces, what should be included and what should be left out

I am in the process of updating a website for the third time in in 2 years, looks like this is going to happen all of the time and several websites are using the same DB. I want to use the same code for all of them and keep it easy to update in the future. So I plan on writing some interfaces and then place the business login in a service to keep things consistent across the board and add in some unit testing.
So I am looking at my current repositories and I am not sure what should be in my Interface and what should be in my Service.
For example I have an Add method - no brainer I have an Add in the interface and an add in the Service.
Then I have an AuthenticateAccountManager method that takes 3 parameters, should this be in both or just the Service and have a simple Get method in my interface (say by Username) and then do the validation against th other 2 properties in the Service.
I also have a QualifyPartner that sets a bool to true, should this just be in the Service and again have a simple Get method in my Interface, trying to keep that as small as possible?
Following the Separation of Concerns principle- AuthenticateAccountManager is a service-level operation. It should call into your repository, which will return the raw User data. The service then authenticates or not based on what is returned by the repository.
The general guideline is that the repository is responsible for retrieval and committing of data only. Interpreting and executing behaviors based on the data is business logic.

Resources