What is Laravel IoC Container in simple words? - laravel

Can anyone explain dependency injection and IoC container in simple and easy words as i am beginner to laravel. thanks

The answer became longer than I wanted it to be in the first place. I included a bit of background information. Still if you're looking for short term explanations, read the first paragraph of the IoC-Container and the bold passages.
Dependency Injection
Dependency Injection is a design pattern, that does what the name states. It injects objects into the constructor or methods of other objects, so that one object depends on one or more other objects.
<?php
class DatabaseWriter {
protected $db;
public function __construct(DatabaseAdapter $db)
{
$this->db = $db;
}
public function write()
{
$this->db->query('...');
}
}
You can see that we require the classes constructor a DatabaseAdapter instance to be passed. Since we are doing that in the constructor, an object of that class cannot be instantiated without it: We are injecting a dependency. Now, that we know that the DatabaseAdapter is always existent within the class we can easily rely on it.
The write() method just calls methods on the adapter, since we definitely know it exists because we made use of DI.
The enormous advantage of using DI instead of misusing static classes, god objects, and other stuff like that is, that you can easily track down where the dependencies come from.
The other huge advantage is, that you can easily swap out dependencies. If you want to use another implementation of your dependency just pass it to the constructor. You don't need to hunt down hardcoded instances anymore in order to be able to swap them.
Leaving aside the fact that by using Dependency Injection you will easily be able to Unit-Test your classes, since you can just mock the dependencies which is hardly possible with hardcoded dependencies.
The three types of Dependency Injection
Constructor Injection
The type of Dependency Injection explained above is called Constructor Injection. That simply means that dependencies are passed as arguments to the classes constructor. The dependencies are then stored as properties and thus made available in all methods of the class. The big advantage here is, that a object of the class cannot exist without passing the dependencies.
Setter Injection
This type makes use of dedicated methods to inject dependencies. Instead of using the constructor. The advantage of using Setter Injection is, that you can add dependencies to an object after it has been created. It's commonly used for optional dependencies. Setter Injection is also great to declutter your constructor and have your dependencies only in methods where you need them.
<?php
class RegisterUserService {
protected $logger;
public function setLogger( Logger $logger )
{
$this->logger = $logger;
}
public function registerUser()
{
// Do stuff to register the user
if($this->logger)
$this->logger->log("User has been registered");
}
}
$service = new RegisterUserService;
$service->registerUser(); // Nothing is Logged
$service->setLogger(new ConcreteLogger);
$service->registerUser(); // Now we log
The object can be instantiated without any dependencies. There is a method to inject the dependency (setLogger()) which can be called optionally. Now it's up to the methods implementation to either make use of the dependency or not (if it's not set).
It's worth pointing out to be cautious with Setter Injection. Calling methods or accessing attributes on a dependency that has not yet been injected will result in a nasty Fatal error: Call to a member function XXX() on a non-object . Therefore everytime the dependency is accessed it has to be null-checked first. A much cleaner way to go about this would be to use the Null Object Pattern and to move the dependency into the constructor (as optional argument, if nothing is passed the null object is created inside the class)
Interface Injection
The idea of interface injection is basically, that the method(s) to inject a dependency is defined in an interface. The class that is going to need the dependency must implement the interface. Hereby it is ensured that the needed dependency can be properly injected into the dependent object. It's a stricter form of the previously explained Setter Injection.
<?php
interface Database {
public function query();
}
interface InjectDatabaseAccess {
// The user of this interface MUST provide
// a concrete of Database through this method
public function injectDatabase( Database $db );
}
class MySQL implements Database {
public function query($args)
{
// Execute Query
}
}
class DbDoer implements InjectDatabaseAccess {
protected $db;
public function injectDatabase( Database $db )
{
$this->db = $db;
}
public function doSomethingInDb($args)
{
$this->db->query();
}
}
$user = new DbDoer();
$user->injectDatabase( new MySQL );
$user->doSomethingInDb($stuff);
The meaningfulness of Interface Injection is open to dispute. Personally I have never used it. I prefer Constructor Injection over it. That allows me to accomplish the exact same task without the need of additional interfaces on the injectors side.
Dependency Inversion
Instead of depending on a concrete instance we can also depend on abstractions.
<?php
class DatabaseWriter {
protected $db;
public function __construct(DatabaseAdapterInterface $db)
{
$this->db = $db;
}
public function write()
{
$this->db->query('...');
}
}
Now we inverted the control. Instead of relying on a concrete instance, we can now inject any instance that consumes the type hinted interface. The interface takes care that the later concrete instance implements all the methods that we are going to use, so that we can still rely on them in the dependent classes.
Make sure you get that one, because it is a core concept of the IoC-Container.
The IoC Container
In the shortest terms I can think of I would describe the IoC container like that:
The IoC-Container is a component that knows how instances are created and knows of all their underlying dependencies and how to resolve them.
If we take our example above, imagine that the DatabaseAdapter itself has it's own dependencies.
class ConcreteDatabaseAdapter implements DatabaseAdapterInterface{
protected $driver;
public function __construct(DatabaseDriverInterface $driver)
{
$this->driver = $driver;
}
}
So in order to be able to use the DatabaseAdapter you would need to pass in a instance of the DatabaseDriverInterface abstraction as a dependency.
But your DatabaseWriter class does not know about it, nor should it. The DatabaseWriter should not care about how the DatabaseAdapter works, it should only care about that a DatabaseAdapter is passed and not how it needs to be created. That's where the IoC-Container comes in handy.
App::bind('DatabaseWriter', function(){
return new DatabaseWriter(
new ConcreteDatabaseAdapter(new ConcreteDatabaseDriver)
);
});
As I already said, the DatabaseWriter itself does not know anything about the dependencies of it's dependencies. But the IoC-Container knows all about them and also knows where to find them. So eventually when the DatabaseWriter class is going to be instantiated, the IoC-Container first is asked how it needs to be instantiated. That's what the IoC-Container does.
Simply spoken (if you are into design patterns). It's a bit of a combination of a Dependency Injection Container (which I already explained above) and a Service Locator.

consider you have a Car class like bellow :
class Car
{
protected $wheels;
protected $engine;
public function __construct()
{
$this->engine = new Engine('BMW Engine');
$this->wheels = array(
new Wheel('some Wheel Brand'),
new Wheel('some Wheel Brand'),
new Wheel('some Wheel Brand'),
new Wheel('some Wheel Brand')
);
}
public function go()
{
//do fun stuff here
}
}
now think about reusing your code and for example you want to have another car class which is for Toyota company.
you should write exactly above code with just a little editing as below :
class AnotherCar
{
protected $wheels;
protected $engine;
public function __construct()
{
$this->engine = new Engine('Toyota Engine');
$this->wheels = array(new Wheel('some Wheel Brand'),
new Wheel('some Wheel Brand'),
new Wheel('some Wheel Brand'),
new Wheel('some Wheel Brand'));
}
public function go()
{
//do fun stuff here
}
}
your code will grow and grow and will be a pain if you don't use DI(Dependency Injection) or IoC(Inversion Of Control).
lets talk about what are the above code problems :
1- its not reusable .
2- it doesn't care about performance (Volume of code in your Ram , ...)
3- your code grows and you will not understand it yourself after a time .
...
so lets use DI and solve the problem
class Car
{
protected $wheels;
protected $engine;
public function __construct($myWheels , $myEngine)
{
$this->engine = $myEngine;
$this->wheels = $myWheels;
}
public function go()
{
//do fun stuff here
}
}
now easily you can create every car object with above Car class like below :
$BMW = new Car (new Engine('BMW' , array(new Wheel('wheel beand') ,new Wheel('wheel beand') ,new Wheel('wheel beand') ,new Wheel('wheel beand') )));
see !
much easier ! also your code is much readable and reusable !
lets consider you have a big project that have so many classes that probably lot of objects and classes depends on other objects and classes.
it will bother you to keep in mind while working that which class depends on what classes and ...
this is where IOC comes in and solve the problems.
IOC pattern or maybe solution is not really easy to understand you should face to problems I mentioned earlier .
IOC just is neede in big projects !
in java Spring is one of the most famous IOC container
and what IOC does???
it contains lots of config file ( or some IOC container configs are in source code and also some of them have user interface to configs)
and this configs contain relation between class and which class for loading depend on which classes
this also is a big help for lazy loading !
just when you need to load an object you load its dependecies !

Related

Dependency Injection in Laravel 5 Package To Use or Not To Use

I am developing a package for Laravel 5, I decided to benefit from dependency injection in my package when using the Core classes of Laravel, but after reading more and also having asked this question
Best approach for Dependency Injection in Laravel 5 package
Now I came up with the idea that if we are using Facades so much and calling static methods like FaceadeName:nameOfMethod the Container actually creates an object for us and calls its method, so to some extend using dependency injection for laravel for classes which are also available through the Facades are is almost useless.
For example having this class:
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');
}
}
doing this:
App::bind('lang', function($app)
{
return new \Lang();
});
and then in the function:
public function myFunction()
{
$lang = \App::make('lang');
$this->text = $lang::get('package::all.text1');
}
is almost useless because we bind something to container that is already bound there
It is not a great idea to change the myFunction to
public function myFunction(\Lang $lang){
$this->text = $lang::get('package::all.text1');
}
as well, it might look like method injection but it doesn't bring so much advantages. Therefore it would be better not to use dependency injection for Facades in Laravel.
Please let me know if I am right or not and please argue my opinion with the right answer if I am wrong.
Facades provide a way of accessing the container through a class, so when you're accessing \Lang::function() you're actually calling app('translator')->function(). So in you're above example when you're binding the Lang facade into the container, you've then bound it twice, which isn't quite what you want.
All Laravel's functionality is already bound into the container and can be accessed by calling app('object'). You can see all the bindings here http://laravel.com/docs/5.0/facades
For dependency injection, you shouldn't be trying to inject the facades, but rather the classes the facades are already referencing. So for example, the \Lang facade references Illuminate\Translation\Translator which is bound to the container as translator
In your classes you can do the following
use App\Http\Controllers\Controller;
use Illuminate\Translation\Translator;
class MyController extends Controller
{
protected $translator;
// Dependency injection example
public function __construct(Translator $translator)
{
$this->translator = $translator;
}
public function index()
{
$text = $this->translator->get('package::all.text1');
}
// Method injection example
public function myFunction(Translator $translator)
{
$text = $translator->get('package::all.text1');
}
}

Laravel 4 Inversion of Control

I'm watching a video explaining the basics of laravel's IoC container, and I'm having trouble understanding what this code is doing. Specifically, I don't understand the parameter in the constructor function of the UserRepository class. I haven't had much luck finding an example of this syntax on the php site.
http://vimeo.com/53009943
<?php
class UserRepository {
protected $something;
public function __construct(Something $something)
{
$this->something = $something;
}
}
class Something {}
?>
Quoting Laravel's documentation:
There are two ways the IoC container can resolve dependencies: via
Closure callbacks or automatic resolution.
But first, what is a dependency? In the code that you have posted, the UserRepository class has one dependency, which is the Something class. It means that UserRepository is going to depend on Something somewhere in its code. Instead of using it directly, by doing something like this
$something = new Something;
$something->doSomethingElse();
it is being injected in its constructor function. This technique is known as dependency injection. So, these code snippets would do the same, without and with dependency injection.
// Without DI
class UserRepository {
public function doSomething()
{
$something = new Something();
return $something->doSomethingElse();
}
}
Now, using DI, which would be the same as you posted:
// With DI
class UserRepository {
public function __construct(Something $something)
{
$this->something = $something;
}
public function doSomething()
{
return $this->something->doSomethingElse();
}
}
You are saying that you don't understand the parameter being passed in the constructor __constructor(Something $something). That line is telling PHP that the constructor expects one parameter, $something, which must be an instance of the Something class. This is known as type hinting. Passing a parameter which is not an instance of Something (or any subclass), will throw an exception.
Finally, let's go back to the IoC container. We've said before that its function is to resolve dependencies, and it can do it in two ways.
First one, Closure callbacks:
// This is telling Laravel that whenever we do
// App::make('user.repository'), it must return whatever
// we are returning in this function
App::bind('UserRepository', function($app)
{
return new UserRepository(new Something);
});
Second one, automatic resolution
class UserRepository {
protected $something;
public function __construct(Something $something)
{
$this->something = $something;
}
}
// Now when we do this
// Laravel will be smart enough to create the constructor
// parameter for you, in this case, a new Something instance
$userRepo = App::make('UserRepository');
This is specially helpful and allows your classes to be more flexible, when using interfaces as parameters for your constructors.

How to inject ISession into Repository correctly?

Please correct me on the following scenario. ( Question is at the end)
(I asked a similar question that was un-organized and it was voted to close. So I have summarized the question here into a scope that can be replied with exact answers.)
I am developing a web application with multiple layers using nhibernate as ORM. My layer structure is as follow
Model Layer
Repository Layer
Services Layer
UI Layer
with the above layers, the classes and interfaces are placed as below.
ProductController.cs (UI Layer)
public class ProductController : Controller
{
ProductServices _ProductServices;
NHibernate.ISession _Session;
public ProductController()
{
_Session = SessionManager.GetCurrentSession();
_ProductServices = new ProductServices(
new ProductRepository(), _Session);
}
// Cont..
}
ProductServices.cs (Service Layer)
public class ProductServices : IProductServices
{
protected IProductRepository _ProductRepository;
protected NHibernate.ISession _Session;
public ProductServices(IProductRepository productRepository,
NHibernate.ISession session)
{
_ProductRepository = productRepository;
_Session = session;
_ProductRepository.SetSession(_Session);
}
// cont...
}
ProductRepository.cs (Repository Layer)
public class ProductRepository : IProductRepository
{
NHibernate.ISession _Session;
public void SetSession(NHibernate.ISession session)
{
_Session = session;
}
public IEnumerable<Product> FindAll()
{
return _Session.CreateCriteria<Product>().List<Product>();
}
//cont..
}
From the UI layer, I create the session as request per session and inject into service layer with the help of class constructor. Then set the session of repository with a help of a method.
I am afraid if I pass the _Session directly to repository as constructor, I will not have the control over it under the service layer. Also there is a future extension plan for using a webservice layer.
** Is there a way to ensure in each method of ProductRepository class that _Session is set already, without writing the piece of code if(_Session==null) in each and every method as it is repeating the same code.
** If the above pattern is wrong, Please show me a right way to achieve this goal.
What you are doing amazed me a bit. You applying the constructor injection pattern in the ProductService, which is definitely the way to go. On the other hand you are not injecting the dependencies into the ProductController, but that class is requesting one of those dependencies through a static class (this is the Service Locator anti-pattern) and creates a ProductServices class itself. This makes this class hard to test and makes your application less flexible and maintainable, since you can't easily change, decorate or intercept the use of the ProductServices class, when it's been used in multiple places.
And although you are (correctly) using constructor injection for the dependencies in the ProductServices, you are passing those dependencies on to the product repository, instead of applying the constructor injection pattern on the ProductResopistory as well.
Please show me a right way to achieve this goal.
The right way is to apply the constructor injection pattern everywhere. When you do this, your code will start to look like this:
public class ProductController : Controller
{
private ProductServices _ProductServices;
public ProductController(ProductServices services)
{
_ProductServices = services;
}
// Cont..
}
public class ProductServices : IProductServices
{
private IProductRepository _ProductRepository;
public ProductServices(
IProductRepository productRepository)
{
_ProductRepository = productRepository;
}
// cont...
}
public class ProductRepository : IProductRepository
{
private ISession _Session;
public ProductRepository (ISession session)
{
_Session = session;
}
public IEnumerable<Product> FindAll()
{
return _Session
.CreateCriteria<Product>().List<Product>();
}
//cont..
}
See how each class only takes in dependencies that it uses itself. So the ProductController and ProductServices don't depend on ISession (I made the assumption that only ProductRepoistory needs ISession). See how -from a class's perspective- everything is much simpler now?
Did we actually solve a problem here? It seems like we just moved the problem of wiring all classes together up the dependency graph. Yes we did move the problem. And this is a good thing. Now each class can be tested in isolation, is easier to follow, and the application as a whole is more maintainable.
Somewhere in the application however, a ProductController must be created. This could look like this:
new ProductController(
new ProductServices(
new ProductRepository(
SessionManager.GetCurrentSession())));
In its normal configuration, ASP.NET MVC will create controller classes for you, and it needs a default constructor to do so. If you want to wire up controllers using constructor injection (which you should definitely do), you need to do something 'special' to get this to work.
ASP.NET MVC allows you to override the default ControllerFactory class. This allows you to decide how to create controller instances. However, when your application starts to grow, it will get really awkward very quickly when you are creating your dependency graphs by hand (as my last example shows). In this case, it would be much better to use a Dependency Injection framework. Most of them contain a feature / package that allows you to integrate it with ASP.NET MVC and automatically allows to use constructor injection on your MVC controllers.
Are we done yet? Well... are we ever? There's one thing in your design that triggered a flag in my brain. Your system contains a class named ProductServices. Although a wild guess, the name Services seems like you wrapped all product related business operations inside that class. Depending on the size of your system, the number of people on your team, and the amount of changes you need to make, this might get problematic. For instance, how to you effectively apply cross-cutting concerns (such as logging, validation, profiling, transaction management, fault tolerance improvements) in such way that to system stays maintainable?
So instead of wrapping all operations in a single ProductServices class, try giving each business transaction / use case its own class and apply the same (generic) interface to all those classes. This description might be a bit vague, but it is a great way to improve the maintainability of small and big systems. You can read more about that here.
You can use a dependency injection container such as Autofac to instantiate your session and manage the lifetime of it. Leave the responsibility of instantiating the session to Autofac and simply inject the ISession interface into any classes that require the dependency. Have a look at this post: Managing NHibernate ISession with Autofac
You will also find this wiki page useful about configuring Autofac with MVC3: http://code.google.com/p/autofac/wiki/MvcIntegration3

Symfony 2: Dependency injection (DI) of Controllers

Is there any chance to make Controllers dependent on their services not via using of service container inside them but through pure constructor dependency injection?
I would like to write controllers in this way:
<?php
class ArticleController extends \Symfony\Bundle\FrameworkBundle\Controller\Controller
{
private $articleFacade;
private $articleRepository;
public function __construct(ArticleFacade $articleFacade, ArticleRepository $articleRepository)
{
$this->articleFacade = $articleFacade;
$this->articleRepository = $articleRepository;
}
public function indexAction()
{
...
}
}
Unfortunatelly as I can see Symfony ControllerResolver does new instances of Controllers not via ServiceContainer but via simple return new $controller call.
Absolutely in fact it's recommended and if you look at most 3rd party bundles such as FOSUser you can see that that is exactly what they do.
The trick is to define your controllers as services and then use the service id instead of the class name.
http://symfony.com/doc/current/cookbook/controller/service.html
Keep in mind that you will have to inject all your needed services such as entity managers and you won't usually extend the symfony base class. Of course you could inject the complete container but that tends to be frowned on.

Property Injection without attributes using Ninject in an abstract base controller in MVC3

I have the following code:
public abstract class BaseController : Controller
{
public IUserService UserService { get; set; }
}
All my controllers inherit from this base controller. I started out by configuring it in Ninject using the following code:
kernel.Bind<BaseController>()
.ToSelf()
.WithPropertyValue("UserService", x => x.Kernel.GetService(typeof(IUserService)));
This did not work. I assume it is because of the fact that the BaseController is an abstract class (please confirm my assumption). So I moved on to modify the configuration to:
kernel.Bind<HomeController>()
.ToSelf()
.WithPropertyValue("UserService", x => x.Kernel.GetService(typeof(IUserService)));
This does work. The minor downside is that I now have to configure every controller the same way.
Since I also have DependencyResolver setup in my ASP.NET MVC 3 project I could also remove the above Ninject configuration and modify my base controller to look like:
public IUserService UserService
{
get
{
return DependencyResolver.Current.GetService<IUserService>();
}
}
Is there any benefit to using the fluent configuration as opposed to using the DependencyResolver approach? Is one better than the other? Which approach would be considered a better practice?
It is worth mentioning that I did not want to do constructor injection in my base controller.
A better practice in MVC it is to use constructor injection over property injection. Why did you make your choice like this ?
Using Constructor Injection you states that all dependencies in constructor are necessary for the class to do its job.
Property injection means that the dependencies are optional or that there are the local defaults implementations, so all will work even if you don't provide necessary implementations yourself.
You should really know what you're doing using Property injection or you have no other choice, so the safer approach is to rely on constructor injection.
Now I'll give you my point of view. Other may have other opinions.
DependencyResolver was introduced in MVC 3 for "convenient" service location but for me it's a regular Service locator which for me is also an anti-pattern http://blog.ploeh.dk/2010/02/03/ServiceLocatorIsAnAntiPattern.aspx. I don't use it because I don't like it and there is no benefit in using it.
I prefer to user my controller factory like before and pass the dependencies through constructor.
More the IDependencyResolver has somme issues with some IoC containers (I don't know if it's the case with Ninject). You can read more here : http://mikehadlow.blogspot.com/2011/02/mvc-30-idependencyresolver-interface-is.html
If you need the same dependency in each controller then there seems to be something wrong in your design. Most likely you are handling some kind of cross cutting concern in your base controller. In this case Doing property injection is just treating sympthoms instead of cureing the disease. This should rather be handled by an aspect (e.g. a filter or an interceptor) so that you do not have to pollute your controller with something that does not belong there.
There are many ways to skin the cat they say. You could use conventions-based bindings with .WithPropertyValue() or with .OnActivaction() (as described here).
public class ControllerModule : NinjectModule
{
public override void Load()
{
// Get all controller types derived from the base controller.
IEnumerable<Type> controllerTypes = // ...
foreach (var controllerType in controllerTypes)
{
Bind(controllerType).ToSelf().InRequestScope()
.WithPropertyValue(...);
}
}
}
You could create your own custom implementation of the IInjectionHeuristic interface as described here or your own custom implementation of the IControllerActivator interface.
public class CustomNinjectControllerActivator : IControllerActivator
{
private readonly IKernel kernel;
public CustomNinjectControllerActivator(IKernel kernel)
{
this.kernel = kernel;
}
public IController Create(RequestContext context, Type controllerType)
{
var baseController = kernel.TryGet(controllerType) as BaseController;
if (baseController == null)
{
return null;
}
baseController.UserService = kernel.Get<IUserService>();
return baseController;
}
}
Heck, you could even use the service locator pattern if you are comfortable using it.
public IUserService UserService
{
get { return DependencyResolver.Current.GetService<IUserService>(); }
}
You should choose whichever solution is easiest to implement, test and maintain, and of course provides the desired behavior.

Resources