I am developing a package for Laravel 5, and now I need to benefit from dependency injection to have a more scalable and relaible application, I don't know which approach is the best to take and why, this is a piece of my code and I need to injected the Lang class dependency
class MyController extends \App\Http\Controllers\Controller
{
public $text;
public $lang;
public function __construct()
{
// Some codes here
}
public function myFunction(){
$this->text = \Lang::get('package::all.text1');
}
}
In this link http://laravel.com/docs/4.2/ioc 2 approaches are suggested, Basic Usage and Automatic Resolution based on my understanding from the link
taking the first approach I need to add
App::bind('lang', function($app)
{
return new \Lang();
});
to the register part of application and then in the function I'll have something
like this :
public function myFunction()
{
$lang = \App::make('lang');
$this->text = $lang::get('package::all.text1');
}
The other way is to modify the constructor like
public function __construct(Lang $lang)
{
$this->lang = $lang;
}
And then instantiate object from Class like
$myController = App::make('MyController');
Which way is the better way to take for, considering that this class is a Controller and it will be called in the routes file, or please correct me if my understanding from the link is not right. please also inform me why you suggest any of those approaches.
It should be noted that using local IoC resolution ($app->make() stylee) is not much better than using the facades directly (Lang::get() stylee) - you're still very much relying on Laravel's specific classes without really making your code explicitly state that it needs these exact classes. So the general advice is to, as much as possible, code to an interface if you want your code to be as portable as possible.
Of course there are a couple of big downsides to this currently in PHP development:
These interfaces are not generally defined (except the PSR-3 LoggerInterface interface) so you still have to rely on a particular instance of the interface (in this case, Laravel's).
If you decide to make your own generic interface (or the FIG eventually creates some of these), the classes that Laravel provides for translation (for example) don't implement it anyway, so you then need to subclass the existing ones just to make it look like it implements your own interface. But hey, that's the current best practice, so I guess if you wanna be using the current best practices, code to an interface, and don't worry for the time being that the interface you're coding to is Laravel-specific.
But anyway, here are my thoughts on your specific question. First off I should say that I haven't actually used Laravel 5 yet (just the 4s), but I have generally followed its development.
If the class I am coding will use a given dependency quite a lot or as a core part of how the class works I will use constructor dependency injection. Examples here are the Request or some Repository class in a controller, or a business logic class in a console command class.
If what I need I only need for a specific purpose (maybe redirecting from a controller and needing to generate a URI) I will resolve a local version from the IoC container ($this->app->make()) and then use that. If I were using Laravel 5 and the method was called by Laravel directly (e.g. a controller's action method) I may use method injection for this, I'm not 100% sure.
As a final note, the general advice is that if your constructor method signatures get too big due to a lot of dependencies:
It's time to have a look at if your code relies too much on external dependencies. Maybe some of the functionality of your class can be extracted to its own class that splits the dependencies between the two.
You should consider using setter methods rather than constructor injection - so instead of accepting a Request object, you have a $class->setRequest() method. The downside of doing this is that you need to tell Laravel's IoC container how to instantiate your object (i.e. that these setters must be called). It's not that big a deal but something worth noting.
Relevant links:
Laravel 5's IoC article
Laravel 5's Controller injection advice
Related
I am a beginner starting out in laravel 5.2 and I think these concepts below should be explained more straight forward than just reading documentation.
Service Providers
Service Container
Contracts
Facades
I think a good explanation and examples that can really help beginners understand how these 4 concepts fit together in the framework.
Service provider :
The so called service providers are the heartbeat of your Laravel application. They are the central element of the initialization process where all the relevant and required code is loaded by PHP. This includes all the essentials from the framework itself, but also any own and custom code you need to load.
Inversion of Control, or IoC :
Can't be explained easly (i only have few ideas about this im not a pro)
Facades :
The Facade pattern is a software design pattern which is often used in object oriented programming. A facade is, in fact, a class wrapping a complex library to provide a simpler and more readable interface to it. The Facade pattern can also be used to provide a unified and well-designed API to a group of complex and poorly designed APIs.
A Laravel facade is a class which provides a static-like interface to services inside the container. These facades, according to the documentation, serve as a proxy for accessing the underlying implementation of the container’s services.
MORE
Contracts :
LARACASTS FREE VIDEO
I know this is not enough! what you are asking is complicated stuff a single answer can't be enough
Ok, so first I agree with the others that laracasts is an amazing resource, that will really go into greater detail and break things down very simply.
That being said, the brief overview is as follows:
Service Container (IoC container) is a laravel core process that allows you to load objects with their dependencies gracefully. For example, If I have a controller method like this:
public function update(Request $request, $id)
{
...
}
IoC container is smart enough to resolve the Request and load up all the dependencies associated with the Request class to make sure it gets instantiated properly.
It also allows you to instantiate classes without having to fully pass along all the dependencies as follows:
class ProductRepo(Product $product)
{
public function get($id)
{
...
}
}
I can reference this class without loading it with dependency injection as follows: (make sure to pass in full namespace)
app('App\ProductRepo')->get($id);
This allows me to not have to pass in a Product Object, Laravel is smart enough to resolve the Product object because the IoC container is doing the magic behind the scenes.
Service Providers are a place for you to lace in custom behavior when booting up or instantiating a class. For example, Laravel by default uses a class called the EventServiceProvider. This class's job is to configure the Event system in Laravel to make sure to include all the custom event listeners you create. So if I wanted to make sure that when the EventDispatcher is being loaded up, it brings in all the necessary dependencies.
Contracts are really simple. They are just an allusion to php object oriented concept of Interfaces. This concept states that there are classes that establish rules. For Example:
interface SearchableInterface
{
public function search($data);
}
class BinarySearch implements SearchableInterface
{
public function search($data)
{
...
}
}
This states that any class that implements the SearchableInterface, must have a function search that accepts one parameter. This creates a 'contract' that any classes that implement the SearchableInterface will have to have this function, or the application will throw an error.
This is great for using interchangeable pieces (siblings) and not having to worry that the class is missing a function you need.
Last but not least is the Facade. I love facades. In a nutshell all this is doing is creating a static representation of a class that was not defined statically. So lets say I have a class that will get a document from S3.
class S3
{
public function get($file)
{
...
}
}
Without a facade you would first have to instantiate and then call get on the class in order to get something from S3.
$s3 = new S3;
$s3->get('myAwesomeFile');
Laravel allows you to easily register Facades so that you can just use this statically for readability and convenience.
S3::get('MyAwesomeFile');
All of this has been an over-simplification of each concept, but goes into some detail about some of the basics of each concept. Hope this helps!
I'm trying to use TDD when writing a class that needs to parse an XML document. Let's say the class is called XMLParser, and its constructor takes in a string for the path to the XML file to parse. I would like to have a Load() method that tries to load this XML into memory, and performs a few checks on the file such as file system errors, whether or not its an XML file, etc.
My question is about alternatives: I've read that it's bad practice to have private methods that you need to test, and that you should be able to just test the public interface and let the private methods do their thing. But in this case, this functionality is pretty important, and I don't think it should be public.
Does anyone have good advice for a scenario like this?
I suggest to redesign your architecture a bit. Currently, you have one high level class with low level functionality embedded. Split that into multiple classes that belong to different layers (I use the term "layer" very loosely here).
Example:
Have one class with the public interface of your current class. (-> High level layer)
Have one class responsible for loading files from disk and handling IO errors (-> Low level layer)
Have one class responsible for validating XML documents (-> Inbetween)
Now you can test all three of these classes independently!
You will see that your high level class will do not much more than just composing the two lower level classes.
Use no access modifier (which is the next up to private) and write the test in the same package.
Good OOD is important but for really important functionality testing is more important. Good practices are always only a guideline and they are good in the general scenario.
You could also try to encapsulate that specific file-checking behaviour in another object and have your parser instantiate it and use it. This is probably what I would do. In this way you could also even use this functionality somewhere else with minimal effort.
You can make a subclass as part of your test package that exposes public accessors to the private methods (which should then be protected).
Public class TestableClass : MyClass
{
public someReturnType TestMethod() {
return base.PrivateMethod();
}
}
Could somebody explain is it possible to have potected, pivate methods in playfamewok's contolles except:
public static void method-action-name() {}
For example if I would have method like this:
protected static int doSomeWork() {}
and this method would be invoked in method-action-name() ..
public static void method-action-name() {
...
int resul = doSomeWork();
...
}
I do not want to have long action-method, so I would like to split it to smaller ones, and then reuse it in other action-methods.
I mean is it ok (from playframework's point of view) to have such method in controller side instead of having them in domain classes? In Spring Framework, we use BP (business process) beans for that, for example.
Is it ok to have such helper methods for business methods in playframework controllers ?
Added after having answer & comments:
For example if I have SearchController class then for that class would be nice to have methods like preSearch1(), preSearch2() what search() method would use, but if I move these methods (1,2) to another class then it should be class with name like SearchHelper then? in package named /src/helpers.. not very nice because they related to search too. But maybe then into /src/bp/SearchBP (bp=business-process). And then in controllers/Search i use /bp/SearchBP that use some Model object with .save() DAO methods (SearchBP can use Domain methods and Search class can use Domain methods as well)
The question here: what class ant package would be nice for those methods? (i just did watch it in examples - there alway very simple usage of controllers that use domain object that why i ask)
yes, you can. Controllers are normal classes, you can add whatever you want. It may not be recommended to clutter them with helper methods, I personally would move them to another class, but you can do what you say.
ANSWER TO EDIT:
The name of the package is "irrelevant", won't change it too much :). You can put them under controllers.support.search which would mean controllers.support is a package with helper classes and the subpackage search contains helper classes and methods related to search.
One alternative (which I like more) is to create a Service layer for that, in a "services" package. You seem to come from a Spring background, so it should come naturally to you. These services are instantiated in the controller as required, or maybe just used via static methods, and do the main business logic. That way the controller only tackles the "higher level" logic.
Another alternative is to move as much of that logic as possible into the Model (avoidid the Anemic Domain Model), and using the Model classes from the controller.
As most decisions in development, which one is better depends on your experience, possible impact/limitations in the codebase, practices in your project... anyway, you can always refactor. Just choose the one that you are more used to (it seems to be Services approach) and code away :)
Any behaviour that's complicated enough to be described as "business logic" (rather than "presentation logic") belongs in the model, not the controller. If your model does nothing but map to/from a set of database tables, then it isn't doing its job properly. Things like permissions and access control, in particular, should be enforced by the model.
I am interested in applying dependency injection to my current project, which makes use of the MVC pattern.
My controllers will call the models and therefore will need to inject the dependencies into the models. To do this, the controller must have the dependencies (such as a database object) in the first place. The controller doesn't need to make use of some of these dependencies (such as the database object), so I feel that it shouldn't be given this dependency. However, it has to have these dependencies if it is to inject them into the model objects.
How can I avoid having dependencies injected into an object just so that it can pass them on? Doing so feels wrong and can result in many dependencies being injected into an object.
Edit: I am using PHP.
I agree with your concerns. It's a code smell to take dependencies for the sole purpose of passing them on to other dependencies.
Depending on the exact interaction between those dependencies, you have a couple of options:
If only one instance of the dependency is needed
If your Controller only needs a single instance of a dependency, then just take a dependency on that instead.
(apologies for the c# code)
Don't do this:
public class MyController
{
public MyController(IDb db)
{
var dep = new MyDependency(db);
// Use dep or save it for later
}
}
Instead, you can do this:
public class MyController
{
public MyController(MyDependency dep)
{
// Use dep or save it for later
}
}
You may want to consider MyDependency behind an interface itself. See also Refactoring to Aggregate Services.
If you need to create multiple instances during the Controller's lifetime
Sometimes, however, you need to create multiple instances dynamically. This is often the case when you need a value that's only available at run-time before you can fully populate a dependency.
In this case, an Abstract Factory is an excellent and universal solution.
I'm not speaking from PHP experience but you should look into Inversion of Control (IOC) Containers.
This question on StackOverflow talks about IOC Containers for PHP. For a quick overview of some of the other benefits of IOC Containers you should check this question, probably one of my favourite on the site. Check the last answer ;)
How can I avoid having dependencies
injected into an object just so that
it can pass them on? Doing so feels
wrong and can result in many
dependencies being injected into an
object.
Most people don't realise that an IOC container makes the need to store temporary dependencies void. This in turn makes your code cleaner and easier to follow. Each class (or module) of your code simply asks for what it needs. IOC Containers can manage object life time, so even if two classes ask for the same dependency independently, they can receive the same instance, which is pretty neat.
I'm updating an php web application that is becoming multilingual, based on the Zend MVC framework, and I'm trying to figure out the best approach to passing the translation object to different classes/layers.
Most of my translation is done at the View level, but there are a few cases where I need to return status messages from custom libraries.
I could just create a property for the library and set the translator, but I'm wondering if there is a better way to integrate a translator object into an existing application?
Hold the users lanaguage in a Memento, and pass that through the program logic, when you need to do that translation use it identify the language.
If using Zend_Translate, it's best option to use register.
Zend_Registry::set('Zend_Translate', $translate);
This way all classes can find it automatically (Zend_Form, Zend_Validate, ...)
You could always instantiate the translator in the bootstrap.php so it is available to all classes as a global. That's how I'd do it since you probably need to use it everywhere. It isn't elegant, but it keeps you from having to add code wherever a class needs to throw an exception or return an error message.
If you don't have that many controllers setup can you not extend the base controller and instantiate the translator there? It should be available for use throughout the system then.
Something like this to extend:
<?php
class BaseController extends Zend_Controller_Action
{
public function init()
{
//setup translation object
}
}
?>
You might want to consider to use a dependency injector container, where the translator is an entry that you pass to the objects you need, without manually constructing the object. That way you can easily test and make more high quality (and testable) code
See other question here
How to use dependency injection in Zend Framework?
or this article about plugging ZF 2 DI into ZF1
http://adam.lundrigan.ca/2011/06/using-zenddi-in-zf1/