Symfony: How to handle common request scope data - symfony

I'm migrating a legacy PHP project (pre-OO) to Symfony2. On every request I have to:
compute some dynamic data (depending on the current date and/or some request parameter)
use that data (multiple times!) in the rendered response.
A naive approach would be:
At the start of every controller method, call some global helper function to compute the data.
At the end of every controller method, pass the data as a parameter to the twig template.
Sounds tedious. Maybe it would be better to:
Create a subscriber for request events that computes the data when a request comes in and provides access to it via getter methods.
Define that subscriber/service as a global twig variable in config.yml.
In twig templates, call the getter methods on that service as needed.
Is that viable?
In particular, are the twig variable/service and the subscriber always identical? Or could the service be a newly created instance?
Is this some sort of misuse? Or is there an officially recommended way for such a use case?
EDIT The data is not only needed in every twig template but in some controllers, too.

Calling a specific method in every Controller-Action would really be a bad solution. Your solution to use a subscriber isn't perfect either.
Without knowing your use-case in detail it´s hard to find a suitable way.
Maybe one approach would be to write a Twig-Extension and injecting a Service into this Extension. The Service would get the Request-Stack via Dependency-Injection and compute the relevant Data. You could then access this data "on demand" through the Twig-Extension during the rendering.
Another approach could be using sub-requests during the rendering (Symfony: How to handle common request scope data)
Maybe these tips already helped you a bit. Otherwise let me know more details, where / how you need the data during the rendering.

Related

Best practice for using Cache Component in Symfony 3

What is the best practice for using the Cache Component in Symfony 3?
Simple example:
If I call getCategoryById (In Repository) from different places (Controller, FormType, Twig function, Listener, ...), how can I verify that the data is cached or not?
Problem:
I can't call Cache Component in Repository and I don't want to write and duplicate the same code in every place ( isHint ... ).
Question:
So what is the best practice? Create an intermediate cache service between all components and the Repository?
Thank you very much :)

Is there a way to perform an OnSaving() validation with ORMLite?

I am working towards replacing an existing "heavy" commercial ORM with ServiceStack's ORMLite. In the heavy ORM, we have the ability to hook an "OnSaving" or "BeforeSaving" method to perform a validation prior to saving to the database. These methods are wired into the MyObject.Save() and occur automatically so that no upstream projects forget to call a validation method.
We currently rely on this mechanism to perform validations, address a few performance denormalizations, and assure data integrity. It's a great way to consolidate the validation into the model. (We can hopefully avoid the arguments about using a repository pattern here.)
I have searched and reviewed several ORMLite examples without finding a way to do this. Can anyone provide some clues?
As far as I know none micro orms don't support events, so you have to do it manually. I don't know your code but I will try to describe what you can do:
1. Add interface IValidation with method Validate() which return collection of i.e validation results
2. Add implementation of IValidation to each object which has OnSaving method.
3. Create generic repository pattern for you micro orm with method Save
4. In method save check if the saving object implement IValidation interface if yes, then invoke Validate() method and if collection is not empty then notify user in any way you want.

Organizing Master-Detail Controllers ASP.Net Web API

I am trying to determine the best way to implement the retrieval of detail records based upon the master's ID.
Obviously you would set up API controllers for both master and detail.
Solutions I've considered:
Have API consumers use OData to get all details filtered by a master ID. While I don't have an issue with this solution, I kinda feel bad putting that onto the API consumer and feel it is something that should be handled internally by the API
Go against the convention of just having the Get/Put/Post/Delete methods and create an action of "GetMastersDetails" on the detail controller and make it accessible via routing. While this would certainly work, I feel this gets away from the whole point of Web API (to an extent).
Create a 3rd controller named "MastersDetailsController" which would have a Get based upon a master ID with different possible return types:
Which would return a list of detail IDs which would then be used to call a Get on the details controller to get those actual details
Which would return a list of actual detail objects. What I don't like about that is having a controller returning a different type than what it is based upon.
Option 2 will be fine. Option 1 opens up a lot more risk depending on your scenario, and what you want to allow the user to get at.
It's not really "against convention" to add custom methods to an ApiController. You can do that however you like. It would only be "against convention" if you did so and used the wrong HTTP methods (i.e. a GET when you're deleting something in your custom method).
I'd go with either #1 or #2.
For #1, OData support enables not only the scenario you describe but offers a lot of additional functionality which might be desired in the future.
For #2, I don't think it gets away from the point of Web API's. Maybe a bit from a true RESTful service, but it's easy to implement and easy to understand.

ASP.NET. Is it better to pass an entire entity to a method or pass each property of this entity as parameters?

We're developing a business ASP.NET application. Is it better to pass an entire entity to a method or pass each property of this entity as parameters? What is the best practice?
Case 1. Pass Customer entity to a manager - InsertCustomer(Customer cust)
Case 2. Pass each property as a parameter - InsertCustomer(string name, string address...etc)
P.S. We're using Entity Framework as our data access layer
Pass the entire entity, not only for reasons given in the other answers, but generally methods with long parameter chains are bad. They are prone to error, and tough to work with from a development standpoint (just look at Interop with Office)
In general, if I see I am getting too many parameters (usually more than three), either I have a method trying to do too much, or I explore ways of encapsulating this data in a struct.
You should pass the entire entity as when you update the entity, e.g. add or remove members you do not have to update all your method calls in all your layers. You only need to change your datalayer and the layer where you are consuming the entity. asp.net is Object Oriented and therefore you should orientate your code around your objects
The whole concept of object orientation requires objects to be passed around. If all is happening internally I would go with this.
If this is being posted to a webservice / across a network etc you would need to serialize, and hence may find it better to pass each individual parameter, especially if the receiving framework is different.
Don't forget your Strings etc are all objects too.
I agree with another poster, passing a whole entity "encapsulates" everything so that it can be updated/modified so you have less to worry about.

How does asp.net mvc figure it out?

How is it that I can create a method in the controller and just put some arguments and it figures it out after I click on a form submit? Under the hood, how does it find the right method and how does it figure out that I just want those arguments?
In a nutshell:
The routing engine handles the HttpRequest, and checks the requested URL. When it finds the first route match, it creates a new instance of MvcRouteHandler and passes it the broken-up tokens of the URL in a RouteValueDictionary.
The route's MvcRouteHandler takes the request, and tries to instantiate a controller class instance. By convention, it looks for a class called "XXXXXXController", where the X's are replaced by the {controller} parameter in the route.
Once it finds the controller, it invokes the appropriate method on it, given by the {action} parameter of the route. Any named arguments, such as {id}, that exist in the route, are passed as parameters to the method.
Basically, everything that ASP.Net MVC "knows" comes from the route information. It can't divine the parameters from thin air - they have to come from the route parsing. If the information isn't present in the requested URL, it can't be passed into the method.
It should also be noted that you can override the behaviour of the framework by making your routes use alternate handlers instead of MvcRouteHandler. The framework is quite extensible, so you can plug in custom functionality at many points.
There's quite a bit of code in play for controller, action and view resolution, as well as the ModelBinders. So much that it'd probably be best for you to look into specific portions of the framework and ask a more detailed question to get much of an answer.
Luckily, the ASP.NET MVC framework has been open-sourced, so if you're curious as to how it all works, you can get the code and look through it yourself. Its excellent code to read through and you're sure to learn something.
More to the point of your question, however, you should look at the System.Web.Mvc.MvcHandler and System.Web.Mvc.ControllerActionInvoker classes, which should lead you down the right path for answering your questions.

Resources