i'm looking for a larger example of dependency injection and how it can be implemented. If class A depends on class B and passes a reference of class C to B's constructor, must not class A also take a reference to class C in it's constructor? This means that the main method in the application should create all classes really, which sounds wierd?
I understand that using DI frameworks we can have it in XML files somehow, but that sounds like it could be hard to quickly see what type that really is instanciated? Especially if it a very large application.
You are correct and each DI framework has a different way of managing it.
Some use attributes on the properties etc to denote dependency and then "automagically" supply an instance of the correct type, while others (say castle windsor for .net) allow xml configuration, fluent or other methods for "wiring up" the dependency graph.
Also no, class A takes a built reference to an instance of B which was built using an instance of C. A needs to know nothing about C unless exposed via B.
public class C { }
public class B { public B(C c) { ... }}
public class A { public A(B b) { ... }}
// manual wireup
C c = new C();
B b = new B(c);
A a = new A(b);
// DI framework
InversionOfControlContainer container = new InversionOfControlContainer(... some configuration);
A a = container.ResolveInstanceOf<A>();
// container dynamically resolves the dependencies of A.
// it doesnt matter if the dependency chain on A is 100 classes long or 3.
// you need an instance of A and it will give you one.
Hope that helps.
to answer your question about classes A,B,and C, A only needs a reference to B.
Most DI frameworks do not require you to use XML for configuration. In fact, many people prefer not to use it. You can explicitly set things up in code, or use some kind of conventions or attributes for the container to infer what objects should fulfil dependencies.
Most DI frameworks have a facility for "lazy loading" to avoid the creation of every single class up front. Or you could inject your own "factory or builder" objects to create things closer to the time when they will be used
You've not said what language you are using. My example below is in C# using the Unity container. (obviously normally you would use interfaces rather than concrete types):
container = new UnityContainer();
container.RegisterType<C>();
container.RegisterType<B>();
A a = container.Resolve<A>();
here's a few examples from the PHP Language, hope this helps you understand
class Users
{
var $Database;
public function __construct(Database $DB)
{
$this->Database = $DB;
}
}
$Database = Database::getInstance();
$Users = new Users($Database);
From this example the new keyword is used in the method getInstance(), you can also do
$Users = new Users(Database::getInstance());
Or another way to tackle this is
class Users
{
/*Dependencies*/
private $database,$fileWriter;
public function addDependency($Name,$Object)
{
$this->$Name = $Object;
return $this;
}
}
$Users = new Users();
$Users->addDependency('database',new Database)->addDependency('fileWriter',new FileWriter);
Update:
to be honest, I never use Dependency Injection as all its doing is passing objects into classes to create a local scope.
I tend to create a global entity, and store objects within that so there only ever stored in 1 variable.
Let me show you a small example:
abstract class Registry
{
static $objects = array();
public function get($name)
{
return isset(self::$objects[$name]) ? self::$objects[$name] : null;
}
public function set($name,$object)
{
self::$objects[$name] = $object;
}
}
Ok the beauty of this type of class is
its very lightweight
it has a global scope
you can store anything such as resources
When your system loads up and your including and initializing all your objects you can just store them in here like so:
Registry::add('Database',new Database());
Registry::add('Reporter',new Reporter());
Where ever you are within your runtime you can just use this like a global variable:
class Users
{
public function getUserById($id)
{
$query = "SELECT * FROM users WHERE user_id = :id";
$resource = Registry::get("Database")->prepare($query);
$resource->bindParam(':id',$id,PDO::PARAM_INT);
if($resource->execute())
{
//etc
}else
{
Registry::get('Reporter')->Add("Unable to select getUserById");
}
}
}
i see this way of object passing is much cleaner
If anybody is still looking for a good example which shows DI without IoC Containers (poor man's DI) and also with IoC Container (Unity in this example) and registering the types in code and also in XML you can check this out: https://dannyvanderkraan.wordpress.com/2015/06/15/real-world-example-of-dependeny-injection/
Related
I am newbie for Guice and seeking help for the following use case :
I have developed one package say (PCKG) where the entry class of that package depends on other class like:
A : Entry point class --> #Inject A(B b) {}
B in turn is dependent on C and D like --> #Inject B(C c, D d) {}
In my binding module I am doing :
bind(BInterface).to(Bimpl);
bind(CInterface).to(CImpl);
...
Note I am not providing binding information for A as i want to provide its binding by its consumer class. (this is how the design is so my request is to keep the discussion on main problem rather than design).
Now my consumer class is doing like:
AModule extends PrivateModule {
protected void configure() {
bind(AInterface.class).annotatedWith(AImpl.class);
}
}
Also in my consumer package:
.(new PCKGModule(), new AModule())
Q1. Am i doing the bindings correctly in consumer class. I am confused because when i am doing some internal testing as below in my consumer package:
class testModule {
bind(BInterface).to(Bimpl);
bind(CInterface).to(CImpl)...
}
class TestApp {
public static void main(..) {
Guice.createInstance(new testModule());
Injector inj = Guice.createInstance(new AModule());
A obj = inj.getInstance(A.class);
}
}
It is throwing Guice creation exception.Please help me get rid of this situation.
Also one of my friend who is also naive to Guice was suggesting that I need to create B's instance in AModule using Provides annotation. But i really didn't get his point.
Your main method should look like this:
class TestApp {
public static void main(..) {
Injector injector = Guice.createInjector(new TestModule(), new AModule());
A obj = injector.getInstance(A.class);
}
Note that the Java convention is for class names to have the first letter capitalised.
I'm pretty sure your implementation of AModule isn't doing what you think it's doing either, but it's hard to be certain based on the information you've provided. Most likely, you mean to do this:
bind(AInterface.class).to(AImpl.class)`
There's no need to do anything "special" with A's binding. Guice resolves all the recursion for you. That's part of its "magic".
annotatedWith() is used together with to() or toInstance(), like this:
bind(AInterface.class).to(AImpl.class).annotatedWIth(Foo.class);
bind(AInterface.class).to(ZImpl.class).annotatedWIth(Bar.class);
Then you can inject different implementations by annotating your injection points, e.g.:
#Inject
MyInjectionPoint(#Foo AInterface getsAImpl, #Bar AInterface getsZImpl) {
....
}
It's worth also pointing out that you can potentially save yourself some boilerplate by not bothering with the binding modules (depending how your code is arranged) and using JIT bindings:
#ImplementedBy(AImpl.class)
public interface AInterface {
....
}
These effectively act as "defaults" which are overridden by explicit bindings, if they exist.
I have a class that serves as a model for some data I get from a server. This data starts as an unwieldy xml object where text nodes have attributes so the json format I convert it into does not have simple string values. Instead I have:
#Injectable()
export class FooString {
_attr: string;
value: string;
isReadOnly(): boolean {
return this._attr && this._attr === 'ReadOnly';
}
isHidden(): boolean {
return this._attr && this._attr === 'Hid';
}
}
Then my model is like:
#Injectable()
export class Payment {
constructor(
public FooId: FooString,
public FooStat: FooString,
public FooName: FooString ) { }
}
Everything ends up with the same instance of FooString. How do I get discrete instances for each of them?
I have tried a factory, but it still only creates a single instance:
export let fooStringProvider = provide(FooString, {
useFactory: (): FooString => {
console.log('in foostring factory');
return new FooString();
}
});
new FooString();
new Payment();
;-)
Why using DI when they don't have dependencies and you don't want to maintain single instances per provider. Therefore, just use new.
When to use DI
There are a few criterias when using DI instead of new the right thing:
If you want Angular to maintain and share instances
If you want to work with an interface or base class but then you want to configure from the outside what implementation should actually be used at runtime - like the MockBackend for Http during testing.
If you class has dependencies to instances and/or values provided by DI
If you want to be able to easily test classes in isolation (https://en.wikipedia.org/wiki/Inversion_of_control)
probably others ...
If there are good arguments to use DI, but you also want new instances then you can just provide a factory.
This answer https://stackoverflow.com/a/36046754/217408 contains a concrete example how to do that.
Using DI is usually a good idea. There are IMHO no strong arguments against using DI. Only when none of the above arguments apply and providing factories is too cumbersome, use new Xxx() instead.
How can I create a Singleton instance in di.dart?
Seems like if I do this:
module = new Module()
..bind(GameRepository)
..bind(MessageFactory)
..bind(Broadcaster);
my GameRepository gets instantiated multiple times if when I do
injector.get(GameRepository)
I tried to do
..bind(GameRepository, toValue: new GameRepository())
and that seems to work, but it's easy because GameRepository has no parameter, but shouldn't there be a way to tell the di framework to bind it as a singleton without requiring me to instantiate it (and maintain its constructor call?)
edit:
#Günter, I do want a Singleton, however in my case I want to use my GameRepository from my redstone.dart resource AND from outside too. So I bind the GameRepository and then do this:
// To use it outside of the resource
injector = new ModuleInjector([modules.getProductionModule()]);
// To use it in redstone
app.addModule(module);
And now I can see that redstone hold a different reference on GameRepository from the one I get when I do injector.get(GameRepository)
I don't know if the question has become too specific though :P
As far as I know DI always returns the same instance, therefore everything is a singleton. If you don't want singletons you can bind a factory.
For more details see https://stackoverflow.com/a/22944185/217408
How about using a factory constructor with the singleton pattern in an implementation or extension of that class
class GameRepositorySingleton extends GameRepository{
static GameRepository _instance;
factory GameRepositorySingleton (A a, B b, ...){
if (_instance == null)
{
_instance = new GameRepository (a, b);
}
return _instance;
}
}
and then you can use it in DI like this
module = new Module()
..bind(GameRepository, toImplementation: GameRepositorySingleton);
To be honest I haven't tried this out. Tell me if it works. You might have to change extends to implements if the editor complains that GameRepository isn't a GameRepositorySingleton.
So I ended up doing this for now. As I need DI outside of redstone for now, I have an injector at top-level. Ideally I could share the injector with Redstone but that doesn't seem to be possible as far as I know. I've opened an issue here. So for now, I think the best way to share a singleton instante between redstone and my code would be something along these lines.
// in my top-level main()
ModuleInjector injector = new ModuleInjector([new Module()..bind(GameRepository)]);
// setup of redstone
GameRepository repo = injector.get(GameRepository);
app.addModule(new Module()..bind(GameRepository, toValue: repo));
// in my redstone resource
#app.Group('/games')
class GamesResource {
GameRepository gameRepository;
Games(this.gameRepository);
}
Let's say we have class:
public class WithDependencies
{
public WithDependencies(IAmDependencyOne first, IAmDependencyTwo second)
// ...
}
Now the question. How do you create objects of WithDependencies class in an application?
I know there are many ways.
new WithDependencies(new DependencyOne(), new DependencyTwo());
new WithDependencies(IoC.Resolve(IDependencyOne), IoC.Resolve(IDependencyTwo());
// register IDependencyOne, IDependencyTwo implementations at app start
IoC.Resolve(WithDependencies);
// register IDependencyOne, IDependencyTwo implementations at app start
// isolate ourselves from concrete IoC Container
MyCustomWithDependenciesFactory.Create();
and so on...
What do you think is the way to do it?
Edit:
Because I don't get answers or I don't understand them I'll try to ask again. Let's say that on some event (button, timer, whatever) I need new object WithDependencies(). How do I create it? Assume IoC container is already configured.
It depends on the context, so it's impossible to provide a single answer. Conceptually you'd be doing something like this from the Composition Root:
var wd = new WithDependencies(new DependencyOne(), new DependencyTwo());
However, even in the absence of a DI Container, the above code isn't always unambiguously the correct answer. In some cases, you might want to share the same dependency among several consumers, like this:
var dep1 = new DependencyOne();
var wd = new WithDependencies(dep1, new DependencyTwo());
var another = AnotherWithDependencies(dep1, new DependencyThree());
In other cases, you might not want to share dependencies, in which case the first option is more correct.
This is just a small glimpse of an entire dimension of DI concerned with Lifetime Management. Many DI Containers can take care of that for you, which is one excellent argument to prefer a DI Container over Poor Man's DI.
Once you start using a DI Container, you should follow the Register Resolve Release pattern when resolving types, letting Auto-wiring take care of the actual composition:
var wd = container.Resolve<WithDependencies>();
The above example assumes that the container is already correctly configured.
If you need to create a dependency which has its own dependencies, you can either A) do it yourself, or B) ask something else to do it for you. Option A negates the benefits of dependency injection (decoupling, etc.), so I would say option B is a better starting point. Now, we have chosen to use the factory pattern, no matter whether it takes the form of a service locator (i.e. IoC.Resolve), a static factory, or an instance factory. The point is that we have delegated that responsibility to an external authority.
There are a number of trade-offs required for static accessors. (I went over them in another answer, so I won't repeat them here.) In order to avoid introducing a dependency on the infrastructure or the container, a solid option is to accept a factory for creating WithDependencies when we need an instance somewhere else:
public class NeedsWithDependencies
{
private readonly IWithDependenciesFactory _withDependenciesFactory;
public NeedsWithDependencies(IWithDependenciesFactory withDependenciesFactory)
{
_withDependenciesFactory = withDependenciesFactory;
}
public void Foo()
{
var withDependencies = _withDependenciesFactory.Create();
...Use the instance...
}
}
Next, we can create a container-specific implementation of the factory:
public class WithDependenciesFactory : IWithDependenciesFactory
{
private readonly IContainer _container;
public WithDependenciesFactory(IContainer container)
{
_container = container
}
public WithDependencies Create()
{
return _container.Resolve<WithDependencies>();
}
}
Now NeedsWithDependencies is completely isolated from any knowledge of how WithDependencies gets created; it also exposes all its dependencies in its constructor, instead of hiding dependencies on static accessors, making it easy to reuse and test.
Defining all those factories can get a little cumbersome, though. I like Autofac's factory relationship type, which will detect parameters of the form Func<TDependency> and automatically inject a function which serves the same purpose as the hand-coded factory above:
public class NeedsWithDependencies
{
private readonly Func<WithDependencies> _withDependenciesFactory;
public NeedsWithDependencies(Func<WithDependencies> withDependenciesFactory)
{
_withDependenciesFactory = withDependenciesFactory;
}
public void Foo()
{
var withDependencies = _withDependenciesFactory();
...Use the instance...
}
}
It also works great with runtime parameters:
public class NeedsWithDependencies
{
private readonly Func<int, WithDependencies> _withDependenciesFactory;
public NeedsWithDependencies(Func<int, WithDependencies> withDependenciesFactory)
{
_withDependenciesFactory = withDependenciesFactory;
}
public void Foo(int x)
{
var withDependencies = _withDependenciesFactory(x);
...Use the instance...
}
}
Sometimes I try to get rid of factories or at least not depend directly on them, so Dependency Injection (without factories) is useful of course.
Therefore I use Google Juice, cause its a small little framework using Java Annotations and you can quickly change your injections / dependencies. Just take a look at it:
http://code.google.com/p/google-guice/
I have been doing my first Test Driven Development project recently and have been learning Ninject and MOQ. This is my first attempt at all this. I've found the TDD approach has been thought provoking, and Ninject and MOQ have been great. The project I am working on has not particularly been the best fit for Ninject as it is a highly configurable C# program that is designed to test the use of a web service interface.
I have broken it up into modules and have interfaces all over the shop, but I am still finding that I am having to use lots of constructor arguments when getting an implementation of a service from the Ninject kernel. For example;
In my Ninject module;
Bind<IDirEnum>().To<DirEnum>()
My DirEnum class;
public class DirEnum : IDirEnum
{
public DirEnum(string filePath, string fileFilter,
bool includeSubDirs)
{
....
In my Configurator class (this is the main entry point) that hooks all the services together;
class Configurator
{
public ConfigureServices(string[] args)
{
ArgParser argParser = new ArgParser(args);
IDirEnum dirEnum = kernel.Get<IDirEnum>(
new ConstructorArgument("filePath", argParser.filePath),
new ConstructorArgument("fileFilter", argParser.fileFilter),
new ConstructorArgument("includeSubDirs", argParser.subDirs)
);
filePath, fileFilter and includeSubDirs are command line options to the program. So far so good. However, being a conscientious kind of guy, I have a test covering this bit of code. I'd like to use a MOQ object. I have created a Ninject module for my tests;
public class TestNinjectModule : NinjectModule
{
internal IDirEnum mockDirEnum {set;get};
Bind<IDirEnum>().ToConstant(mockDirEnum);
}
And in my test I use it like this;
[TestMethod]
public void Test()
{
// Arrange
TestNinjectModule testmodule = new TestNinjectModule();
Mock<IDirEnum> mockDirEnum = new Mock<IDirEnum>();
testModule.mockDirEnum = mockDirEnum;
// Act
Configurator configurator = new Configurator();
configurator.ConfigureServices();
// Assert
here lies my problem! How do I test what values were passed to the
constructor arguments???
So the above shows my problem. How can I test what arguments were passed to the ConstructorArguments of the mock object? My guess is that Ninject is dispensing of the ConstuctorArguments in this case as the Bind does not require them? Can I test this with a MOQ object or do I need to hand code a mock object that implements DirEnum and accepts and 'records' the constructor arguments?
n.b. this code is 'example' code, i.e. I have not reproduced my code verbatim, but I think I have expressed enough to hopefully convey the issues? If you need more context, please ask!
Thanks for looking. Be gentle, this is my first time ;-)
Jim
There are a few problems with the way you designed your application. First of all, you are calling the Ninject kernel directly from within your code. This is called the Service Locator pattern and it is considered an anti-pattern. It makes testing your application much harder and you are already experiencing this. You are trying to mock the Ninject container in your unit test, which complicates things tremendously.
Next, you are injecting primitive types (string, bool) in the constructor of your DirEnum type. I like how MNrydengren states it in the comments:
take "compile-time" dependencies
through constructor parameters and
"run-time" dependencies through method
parameters
It's hard for me to guess what that class should do, but since you are injecting these variables that change at run-time into the DirEnum constructor, you end up with a hard to test application.
There are multiple ways to fix this. Two that come in mind are the use of method injection and the use of a factory. Which one is feasible is up to you.
Using method injection, your Configurator class will look like this:
class Configurator
{
private readonly IDirEnum dirEnum;
// Injecting IDirEnum through the constructor
public Configurator(IDirEnum dirEnum)
{
this.dirEnum = dirEnum;
}
public ConfigureServices(string[] args)
{
var parser = new ArgParser(args);
// Inject the arguments into a method
this.dirEnum.SomeOperation(
argParser.filePath
argParser.fileFilter
argParser.subDirs);
}
}
Using a factory, you would need to define a factory that knows how to create new IDirEnum types:
interface IDirEnumFactory
{
IDirEnum CreateDirEnum(string filePath, string fileFilter,
bool includeSubDirs);
}
Your Configuration class can now depend on the IDirEnumFactory interface:
class Configurator
{
private readonly IDirEnumFactory dirFactory;
// Injecting the factory through the constructor
public Configurator(IDirEnumFactory dirFactory)
{
this.dirFactory = dirFactory;
}
public ConfigureServices(string[] args)
{
var parser = new ArgParser(args);
// Creating a new IDirEnum using the factory
var dirEnum = this.dirFactory.CreateDirEnum(
parser.filePath
parser.fileFilter
parser.subDirs);
}
}
See how in both examples the dependencies get injected into the Configurator class. This is called the Dependency Injection pattern, opposed to the Service Locator pattern, where the Configurator asks for its dependencies by calling into the Ninject kernel.
Now, since your Configurator is completely free from any IoC container what so ever, you can now easily test this class, by injecting a mocked version of the dependency it expects.
What is left is to configure the Ninject container in the top of your application (in DI terminology: the composition root). With the method injection example, your container configuration would stay the same, with the factory example, you will need to replace the Bind<IDirEnum>().To<DirEnum>() line with something as follows:
public static void Bootstrap()
{
kernel.Bind<IDirEnumFactory>().To<DirEnumFactory>();
}
Of course, you will need to create the DirEnumFactory:
class DirEnumFactory : IDirEnumFactory
{
IDirEnum CreateDirEnum(string filePath, string fileFilter,
bool includeSubDirs)
{
return new DirEnum(filePath, fileFilter, includeSubDirs);
}
}
WARNING: Do note that factory abstractions are in most cases not the best design, as explained here.
The last thing you need to do is to create a new Configurator instance. You can simply do this as follows:
public static Configurator CreateConfigurator()
{
return kernel.Get<Configurator>();
}
public static void Main(string[] args)
{
Bootstrap():
var configurator = CreateConfigurator();
configurator.ConfigureServices(args);
}
Here we call the kernel. Although calling the container directly should be prevented, there will always at least be one place in your application where you call the container, simply because it must wire everything up. However, we try to minimize the number of times the container is called directly, because it improves -among other things- the testability of our code.
See how I didn't really answer your question, but showed a way to work around the problem very effectively.
You might still want to test your DI configuration. That's very valid IMO. I do this in my applications. But for this, you often don't need the DI container, or even if your do, this doesn't mean that all your tests should have a dependency on the container. This relationship should only exist for the tests that test the DI configuration itself. Here is a test:
[TestMethod]
public void DependencyConfiguration_IsConfiguredCorrectly()
{
// Arrange
Program.Bootstrap();
// Act
var configurator = Program.CreateConfigurator();
// Assert
Assert.IsNotNull(configurator);
}
This test indirectly depends on Ninject and it will fail when Ninject is not able to construct a new Configurator instance. When you keep your constructors clean from any logic and only use it for storing the taken dependencies in private fields, you can run this, without the risk of calling out to a database, web service or what so ever.
I hope this helps.