Creating Dependent Objects - Dependency Injection

Say we have a class:

public class WithDependencies { public WithDependencies(IAmDependencyOne first, IAmDependencyTwo second) // ... } 

Now the question. How do you create objects of the WithDependencies class in an application? I know that 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 say that on some event (button, timer, whatever) I need new object WithDependencies (). How do I create it? Assume IoC container is already configured.

+4
dependency-injection inversion-of-control ioc-container
source share
3 answers

It depends on the context, so it is not possible to provide one answer. Conceptually, you do something similar from Root of Composition :

 var wd = new WithDependencies(new DependencyOne(), new DependencyTwo()); 

However, even in the absence of a DI container, the above code is not always unambiguously the correct answer. In some cases, you can use the same dependency between multiple consumers, for example:

 var dep1 = new DependencyOne(); var wd = new WithDependencies(dep1, new DependencyTwo()); var another = AnotherWithDependencies(dep1, new DependencyThree()); 

In other cases, you may not want to share the dependencies, in which case the first option is more correct.

This is just a small glimpse of the entire DI dimension associated with Lifetime Management . Many DI containers can take care of this for you, which is one of the excellent arguments for choosing a DI container over a poor DI person.

After you start using the DI container, you must follow the Register Resolve Release pattern when resolving types, allowing Auto-wiring to take care of the actual composition:

 var wd = container.Resolve<WithDependencies>(); 

The above example assumes that the container is already configured correctly.

+3
source share

If you need to create a dependency that has its own dependencies, you can either A) do it yourself, or B) ask for something else to do for you. Option A denies the benefits of dependency injection (decoupling, etc.), so I would say that option B is the best starting point. Now we decided to use the factory template, regardless of whether it takes the form of a service locator (i.e., IoC.Resolve ), a static factory, or an instance of a factory. The fact is that we have delegated this responsibility to an external body.

There are a number of tradeoffs needed for static accessories. ( I looked at them in another answer , so I won’t repeat them here.) To avoid introducing a dependency on the infrastructure or container, is to take a factory to create 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 factory implementation:

 public class WithDependenciesFactory : IWithDependenciesFactory { private readonly IContainer _container; public WithDependenciesFactory(IContainer container) { _container = container } public WithDependencies Create() { return _container.Resolve<WithDependencies>(); } } 

Now NeedsWithDependencies completely isolated from any knowledge of how WithDependencies is created; it also exposes all its dependencies in its constructor instead of hiding dependencies on static accessories, which simplifies reuse and testing.

Defining all of these plants can be a little cumbersome. I like the Autofac factory relationship type , which will determine the parameters of the Func<TDependency> form and automatically introduce a function that performs the same task as the manual factory code 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... } } 
+2
source share

Sometimes I try to get rid of factories or, at least, not directly depend on them, so, of course, it is useful to use injections (without factories).

So I use Google Juice, create a small small structure using Java annotations and you can quickly change your injections / dependencies. Just take a look at this:

http://code.google.com/p/google-guice/

0
source share

All Articles