I have a question regarding dependency injection pattern.
My question is...
If I go for constructor injection, injecting the dependencies for my class, what I get is a "big" constructor with many params.
What if ie. I dont use some of the params in some methods?
Ie. I have a service that exposes many methods. And a constructor with 10 parameters (all dependencies). But not all the methods uses all the dependencies. Some method will use only one dependency, another will use 3 dependencies. But DI container will resolve them all even if non are used.
To me this is a performance penalty of using DI container. Is this true?
It seems your class is doing to much, that it does not comply to the S in SOLID (Single responsibility principle) , maybe you could split the class in multiple smaller classes with less dependencies. The fact that not all dependencies are used by all methods suggests this.
Normally the performance penalty of injecting many dependencies is low, but it depends on the framework you pick. Some will compile methods for this on the fly. You will have to test this. Many dependencies does indicate that your class is doing too much (like Ruben said), so you might want to take a look at that. If creation of an instance of a depedency that you often don't use causes performance problems, you might want to introduce a factory as dependency. I found that the use of factories can solve many problems regarding the use of dependency injection frameworks.
// Constructor
public Consumer(IContextFactory contextFactory)
{
this.contextFactory = contextFactory;
}
public void DoSomething()
{
var context = this.contextFactory.CreateNew();
try
{
// use context here
context.Commit();
}
finally
{
context.Dispose();
}
}
You can also hide some not-yet-needed dependencies behind lazy providers. For instance:
public DataSourceProvider implements Provider<DataSource> {
public DataSource get() {
return lazyGetDataSource();
}
}
The Provider interface is part of javax.inject package.
Actually you can't know which methods are used at runtime when you build your DI container. You would have to deal with that performance penalty or if you know that there are many cases where just a few dependencies are used, you could split your container into several small containers that have less dependencies that are injected.
As rube Says probabily you should review te design of your class to stick to SOLID principles.
Anyway if it is not really necessary I'm used to go for property setter dependency insteadof the constructor. It means that you can create a property for each dependecy you need. That helps also to test the class because you can inject only the dependency you need into the context of the test you are doing instead of stub out all the dependency even if you don't need it
Related
I'm having troubles getting the advantage of a IoC (DI) container like Ninject, Unity or whatever. I understand the concepts as follows:
DI: Injecting a dependency into the class that requires it (preferably via constructor injection). I totally see why the less tight coupling is a good thing.
public MyClass{
ISomeService svc;
public MyClass(ISomeService svc){
svc = svc;
}
public doSomething(){
svc.doSomething();
}
}
Service Locator: When a "container" is used directly inside the class that requires a dependancy, to resolve the dependancy. I do get the point that this generates another dependancy and I also see that basically nothing is getting injected.
public MyClass{
public MyClass(){}
public doSomething(){
ServiceLocator.resolve<ISomeService>().doSomething();
}
}
Now, what confuses me is the concept of a "DI container". To me, it looks exactly like a service locator which - as far as I read - should only be used in the entry point / startup method of an application to register and resolve the dependancies and inject them into the constructors of other classes - and not within a concrete class that needs the dependancy (probably for the same reason why Service locators are considered "bad")
What is the purpose of using the container when I could just create the dependancy and pass it to the constructor?
public void main(){
DIContainer.register<ISomeService>(new SomeService());
// ...
var myclass = new MyClass(DIContainer.resolve<ISomeService>());
myclass.doSomething();
}
Does it really make sense to pass all the dependancies to all classes in the application initialization method? There might be 100 dependancies which will be eventually needed (or not) and just because it's considered a good practice you set create them in the init method?
What is the purpose of using the container when I could just create the dependancy and pass it to the constructor?
DI containers are supposed to help you create an object graph quickly. You just tell it which concrete implementations you want to use for which abstractions (the registration phase), and then it can create any objects you want want (resolve phase).
If you create the dependencies and pass them to the constructor (in the application initialization code), then you are actually doing Pure DI.
I would argue that Pure DI is a better approach in many cases. See my article here
Does it really make sense to pass all the dependancies to all classes in the application initialization method? There might be 100 dependancies which will be eventually needed (or not) and just because it's considered a good practice you set create them in the init method?
I would say yes. You should create the object graph when your application starts up. This is called the composition root.
If you need to create objects after your application has started then you should use factories (mainly abstract factories). And such factories will be created with the other objects in the composition roots.
Your classes shouldn't do much in the constructor, this will make the cost of creating all the dependencies at the composition root low.
However, I would say that it is OK to create some types of objects using the new keyword in special cases. Like when the object is a simple Data Transfer Object (DTO)
My understanding is that a facade is used as an alternative to dependency injection. Please correct if I'm mistaken. What is not clear is when one should use one or the other.
What are the advantages/disadvantages of each approach? How should I determine when to use one or the other?
Lastly, why not use both? I can create a facade that references an interface. It seems Sentry 2 is written this way. Is there a best practice?
FACADES
Facades are not an alternative to dependency injection.
Laravel Facade is an implementation of the Service Locator Pattern, creating a clean and beautiful way of accessing objects:
MyClass::doSomething();
This is the PHP syntax for a static methods, but Laravel changes the game and make them non-static behind the scenes, giving you a beautiful, enjoyable and testable way of writing your applications.
DEPENDENCY INJECTION
Dependency Injection is, basically, a way of passing parameters to your constructors and methods while automatically instatiating them.
class MyClass {
private $property;
public function __construct(MyOtherClass $property)
{
/// Here you can use the magic of Dependency Injection
$this->property = $property
/// $property already is an object of MyOtherClass
}
}
A better construction of it would be using Interfaces on your Dependency Injected constructors:
class MyClass {
private $property;
public function __construct(MyInterface $property)
{
/// Here you can use the magic of Dependency Injection
$this->property = $property
/// $property will receive an object of a concrete class that implements MyInterface
/// This class should be defined in Laravel elsewhere, but this is a way of also make
/// your application easy to maintain, because you can swap implementations of your interfaces
/// easily
}
}
But note that in Laravel you can inject classes and interfaces the same way. To inject interfaces you just have to tell it wich one will be this way:
App::bind('MyInterface', 'MyOtherClass');
This will tell Laravel that every time one of your methods needs an instance of MyInterface it should give it one of MyOtherClass.
What happens here is that this constuctor has a "dependency": MyOtherClass, which will be automatically injected by Laravel using the IoC container. So, when you create an instance of MyClass, Laravel automatically will create an instance of MyOtherClass and put it in the variable $class.
Dependency Injection is just an odd jargon developers created to do something as simple as "automatic generation of parameters".
WHEN TO USE ONE OR THE OTHER?
As you can see, they are completely different things, so you won't ever need to decide between them, but you will have to decide where go to with one or the other in different parts of your application.
Use Facades to ease the way you write your code. For example: it's a good practice to create packages for your application modules, so, to create Facades for those packages is also a way to make them seem like a Laravel public class and accessing them using the static syntax.
Use Dependency Injection every time your class needs to use data or processing from another class. It will make your code testable, because you will be able to "inject" a mock of those dependencies into your class and you will be also exercising the single responsibility principle (take a look at the SOLID principles).
Facades, as noted, are intended to simplify a potentially complicated interface.
Facades are still testable
Laravel's implementation goes a step further and allows you to define the base-class that the Facade "points" to.
This gives a developer the ability to "mock" a Facade - by switching the base-class out with a mock object.
In that sense, you can use them and still have testable code. This is where some confusion lies within the PHP community.
DI is often cited as making your code testable - they make mocking class dependencies easy. (Sidenote: Interfaces and DI have other important reasons for existing!)
Facades, on the other hand, are often cited as making testing harder because you can't "simply inject a mock object" into whatever code you're testing. However, as noted, you can in fact "mock" them.
Facade vs DI
This is where people get confused regarding whether Facades are an alternative to DI or not.
In a sense, they both add a dependency to your class - You can either use DI to add a dependency or you can use a Facade directly - FacadeName::method($param);. (Hopefully you are not instantiating any class directly within another :D ).
This does not make Facades an alternative to DI, but instead, within Laravel, does create a situation where you may decide to add class dependencies one of 2 ways - either using DI or by using a Facade. (You can, of course, use other ways. These "2 ways" are just the most-often used "testable way").
Laravel's Facades are an implementation of the Service Locator pattern, not the Facade pattern.
In my opinion you should avoid service locator within your domain, opting to only use it in your service and web transport layers.
http://martinfowler.com/articles/injection.html#UsingAServiceLocator
I think that in terms of laravel Facades help you keep you code simple and still testable since you can mock facades however might be a bit harder to tell a controllers dependencies if you use facades since they are probably all over the place in your code.
With dependency injection you need to write a bit more code since you need to deal with creating interfaces and services to handle the depenancies however Its a lot more clear later on what a controller depends on since these are clearly mentioned in the controller constructor.
I guess it's a matter of deciding which method you prefer using
When using dependency injection which dependencies do you inject?
I have previously injected all dependencies but have found when doing TDD there are typically two types of dependency:
Those which are genuine external dependencies which may change e.g. ProductRepository
Those which exist purely for testability e.g. Part of the behaviour of the class that has been extracted and injected just for testability
One approach is to inject ALL dependencies like this
public ClassWithExternalDependency(IExternalDependency external,
IExtractedForTestabilityDependency internal)
{
// assign dependencies ...
}
but I've found this can cause dependency bloat in the DI registry.
Another approach is to hide the "testability dependency" like this
public ClassWithExternalDependency(IExternalDependency external)
: this (external, new ConcreteClassOfInternalDependency())
{}
internal ClassWithExternalDependency(IExternalDependency external,
IExtractedForTestabilityDependency internal)
{
// assign dependencies ...
}
This is more effort but seems to make a lot more sense. The downside being not all objects are configured in the DI framework, thereby breaking a "best practice" that I've heard.
Which approach would you advocate and why?
I believe you're better off injecting all of your dependencies. If it starts to get a little unwieldy, that's probably an indication that you need to simplify things a bit or move the dependencies into another object. Feeling the "pain" of your design as you go can be really enlightening.
As for dependency bloat in the registry, you might consider using some sort of conventional binding technique, rather than registering each dependency by hand. Some IoC containers have convention-based type-scanning bindings built into them. For example, here's part of a module I use in a Caliburn WPF application that uses Ninject:
public class AppModule : NinjectModule
{
public override void Load()
{
Bind<IShellPresenter>().To<ShellPresenter>().InSingletonScope();
BindAllResults();
BindAllPresenters();
}
/// <summary>
/// Automatically bind all presenters that haven't already been manually bound
/// </summary>
public void BindAllPresenters()
{
Type[] types = Assembly.GetExecutingAssembly().GetTypes();
IEnumerable<Type> presenterImplementors =
from t in types
where !t.IsInterface
&& t.Name.EndsWith("Presenter")
select t;
presenterImplementors.Run(
implementationType =>
{
if (!Kernel.GetBindings(implementationType).Any())
Bind(implementationType).ToSelf();
});
}
Even though I have dozens of results and presenters running around, I don't have to register them explicitly.
I certainly won't inject all dependencies, because were to stop? Do you want to inject your string dependencies? I only invert the dependencies that I need for unit testing. I want to stub my database (see this example for instance). I want to stub the sending of e-mail messages. I want to stub the system clock. I want to stub writing to the file system.
The thing about inverting as many dependencies as you can, even those that you don't need for testing, is that make unit testing a lot harder and the more you stub out the less you really test how the system really acts. This makes your tests much less reliable. It also complicates your DI configuration in the application root.
I would wire all my non-external dependencies by hand and 'register' only external dependencies. When I say non-external, I mean the objects which belong to my component and which were extracted out to interfaces just for the sake of single responsibility/testability I would never have any other implementations of such interfaces ever. External dependencies are stuff like DB connections, web services, interfaces which don't belong to my component. I would register them as interfaces because their implementations can be switched to stubbed ones for integration testing. Having a small number of components registered in a DI container makes the DI code easier to read and bloat free.
What is your advice?
I found most suitable for me solution - keep injectors and modules in enumeration classes.
Advantages:
injectors and modules created once,
injectors can be used from different classes while running application (not only at bootstrap),
injectors kept in one place and can be easily found.
Example:
import static ru.package.Modules.*;
public enum Injectors {
FOO_INJECTOR(BarModule.module()),
FOO2_INJECTOR(FOO_INJECTOR.injector(),
Bar2Module.module(), FooModule.module());
private final Injector m_injector;
Injectors (Module... modules) {
m_injector = Guice.createInjector(modules);
}
Injectors (Injector parentInjector, Module... modules) {
m_injector = parentInjector.createChildInjector(modules);
}
public Injector injector() {
return m_injector;
}
}
You appear to be fundamentally misunderstanding how dependency injection works. If you are trying to use a reference to Injector anywhere in your code besides the place where you bootstrap the application, you're not using dependency injection, you're using it as a Service Locator instead. You're forced to prepare an Injector whenever you need to test a class and your classes do not make it clear in their constructors exactly what their dependencies are (since who knows what they'll get out of the Injector in some method if they have or can get a reference to it). Actually, using enum as you've described here is even worse than that: you cannot change the configuration at all, even for testing, because your modules are hardcoded into the enum.
With dependency injection, classes declare their dependencies only and allow the Injector, working transparently (after the initial call to get the root application object), to provide all those dependencies. This makes understanding, testing and changing functionality in your code relatively easy. Anyway, I'd suggest learning more about how DI and Guice are intended to be used... you really should not want to do this.
The bigger question is why?
There should be no need to keep the Injector around, because once the injection is done the Injector should be done and should disappear.
If, however, you really need the Injector, couldn't you simply:
#Inject
private Injector injector;
Is this application web based or is it standalone?
On this AutoFac "Best Practices" page (http://code.google.com/p/autofac/wiki/BestPractices), they say:
Don't Pass the Container Around
Giving components access to the container, or storing it in a public static property, or making functions like Resolve() available on a global 'IoC' class defeats the purpose of using dependency injection. Such designs have more in common with the Service Locator pattern.
If components have a dependency on the container, look at how they're using the container to retrieve services, and add those services to the component's (dependency injected) constructor arguments instead.
So what would be a better way to have one component "dynamically" instantiate another? Their second paragraph doesn't cover the case where the component that "may" need to be created will depend on the state of the system. Or when component A needs to create X number of component B.
To abstract away the instantiation of another component, you can use the Factory pattern:
public interface IComponentBFactory
{
IComponentB CreateComponentB();
}
public class ComponentA : IComponentA
{
private IComponentBFactory _componentBFactory;
public ComponentA(IComponentBFactory componentBFactory)
{
_componentBFactory = componentBFactory;
}
public void Foo()
{
var componentB = _componentBFactory.CreateComponentB();
...
}
}
Then the implementation can be registered with the IoC container.
A container is one way of assembling an object graph, but it certainly isn't the only way. It is an implementation detail. Keeping the objects free of this knowledge decouples them from infrastructure concerns. It also keeps them from having to know which version of a dependency to resolve.
Autofac actually has some special functionality for exactly this scenario - the details are on the wiki here: http://code.google.com/p/autofac/wiki/DelegateFactories.
In essence, if A needs to create multiple instances of B, A can take a dependency on Func<B> and Autofac will generate an implementation that returns new Bs out of the container.
The other suggestions above are of course valid - Autofac's approach has a couple of differences:
It avoids the need for a large number of factory interfaces
B (the product of the factory) can still have dependencies injected by the container
Hope this helps!
Nick
An IoC takes the responsibility for determining which version of a dependency a given object should use. This is useful for doing things like creating chains of objects that implement an interface as well as having a dependency on that interface (similar to a chain of command or decorator pattern).
By passing your container, you are putting the onus on the individual object to get the appropriate dependency, so it has to know how to. With typical IoC usage, the object only needs to declare that it has a dependency, not think about selecting between multiple available implementations of that dependency.
Service Locator patterns are more difficult to test and it certainly is more difficult to control dependencies, which may lead to more coupling in your system than you really want.
If you really want something like lazy instantiation you may still opt for the Service Locator style (it doesn't kill you straight away and if you stick to the container's interface it is not too hard to test with some mocking framework). Bear in mind, though that the instantiation of a class that doesn't do much (or anything) in the constructor is immensely cheap.
The container's I have come to know (not autofac so far) will let you modify what dependencies should be injected into which instance depending on the state of the system such that even those decisions can be externalized into the configuration of the container.
This can provide you plenty of flexibility without resorting to implementing interaction with the container based on some state you access in the instance consuming dependencies.