4

Managing Dependency Injection in C# with Autofac explains in a very concise way with downloadable source code

Dependency injection by hand

var di = new EmployeeObserver(employees, new Printer(Console.Out));
di.FindExperts();

with autofac:

ContainerBuilder autofac = new ContainerBuilder();
autofac.Register(o => new EmployeeObserver(o.Resolve<IList<Employee>>(), o.Resolve<IPrinter>()));
autofac.RegisterType<Printer>().As<IPrinter>();
autofac.RegisterInstance(employees).As<IList<Employee>>();
autofac.RegisterInstance(Console.Out).As<TextWriter>();
using (var container = autofac.Build())
{
    container.Resolve<EmployeeObserver>().FindExperts();
}

In some other Q&As, it says we can see the advantage usage of autofac while writing unit test.

Apart from that, could someone give reasons or details more why should I use more complicate code with autofac instead of by manual dependency injection?

It says:

May be on this particular example it's hard to see why this approach is better than configuring dependency injection by hand, but you should notice one important thing - with Autofac each component is configured independently of all the others, and this is what will make a big difference when your application become more complex.

Can you point an example of complex version of this case, that shows advantage of autofac usage vs dependency by hand that I will stuck with?

asdf_enel_hak
  • 7,474
  • 5
  • 42
  • 84
  • 1
    Related: https://stackoverflow.com/questions/32032771/using-dependency-injection-without-any-di-framework – Steven Jul 07 '16 at 11:43
  • Are you sure the other places talk about the use of _autofac_ in unit testing, or just _dependency injection_ in unit testing? Are you asking specifically about the unit testing part, or DI/autofac in general? This is quite a broad subject, so to be answerable on here you need to be quite precise in what your question is. – James Thorpe Jul 07 '16 at 11:45
  • @JamesThorpe Especially not unit testing part, rather latter – asdf_enel_hak Jul 07 '16 at 11:46
  • 1
    From Mark Seemann: [When to use a DI container.](http://blog.ploeh.dk/2012/11/06/WhentouseaDIContainer/) – Matthew Watson Jul 07 '16 at 11:49
  • @MatthewWatson It seems nice reference however could it be done a projection on my question as example in order to digest easily – asdf_enel_hak Jul 07 '16 at 11:55

2 Answers2

3

Using or not using a DI container has no effect on unit testing. When you unit test, you don't use a DI container because unit tests usually deal with a single or a few classes that you can wire together easily.

Please note that whether to use or not use a DI container to compose your objects is still a highly opinionated question. Here I provide a perspective that I have based on my experience using dependency injection in my projects.

In an article of mine, Why DI containers fail with “complex” object graphs, I define the concept of a simple object graph like this:

An object graph of any size and any depth that has the following two attributes:

a) For any interface (or abstraction) at most one class that implements such interface is used in the object graph.

b) For any class, at most one instance is used in the object graph (or multiple instances with the exact same construction parameter arguments). This single instance can be used multiple times in the graph.

When you have a simple object graph, use a DI container.

For an example of a simple object graph, consider that you have 20 service interfaces that is each implemented by a single class. E.g. IEmailService is only implemented by EmailService, and ISMSService is only implemented by SMSService, etc., and that you have 30 ASP.NET controllers each depending on any number of these service interfaces. Also some of the services depend on other service interfaces, e.g. OrderService depends on IEmailService.

When you don't have a simple object graph, i.e., you have a complex object graph (which is the case for most large applications that apply the SOLID principles), don't use a DI container and instead use Pure DI.

If you use a DI container with a complex object graph, you will end up using complex features of the container like named registrations to distinguish between different implementations of the same interface or between objects that take different construction parameters. This will make your composition root hard to maintain.

You might want to a look at this article of mine about how Pure DI can make your composition root clean.

Community
  • 1
  • 1
Yacoub Massad
  • 27,509
  • 2
  • 36
  • 62
2

In some other Q&As, it says we can see the advantage usage of autofac while writing unit test

You've missed the point. The ability to mock dependency, and, hence, to write unit test, is the advantage of dependency injection as a pattern itself.

Advantage of any DI-container (not only Autofac) is ability to configure dependencies somehow and use this configuration in complex scenarios.

Imagine, that you have some class, that depends on some service, which, in turn depends on some other service, and so on.

It is hard to implement this using poor man's DI, but DI-containers can deal with this.

Dennis
  • 37,026
  • 10
  • 82
  • 150
  • I think that the language has gotten in the way. Perhaps @asdf_enel_hak is on the right track with the DI pattern versus the container but has expressed it poorly. – Keith Payne Jul 07 '16 at 23:12