1

I understand the basic concept of IoC, but I have a hard time expanding my vision beyond the initial concept.


Basically, using a DI framework, I should not use anymore the new keyword for objects with dependencies, because then, I am not calling the DI framework resolving method, thus not triggering the chain of resolves.

User wants an object A who needs an object B who wants an object C who wants...

That is what would happen, using a DI Framework. But using the new keyword, I would get left with :

I just instantiate an object A

Question 1 : Am I right ? Wrong ? Or is it again a case of "it depends" ?


I just read an answer of Mark Seemann (https://stackoverflow.com/a/2490797/2671072) where he says :

A DI Container should resolve the entire dependency graph in the application's Composition Root and get out of the way.

Question 2 : Does he imply that the only time the DI framework should be called (to resolve something) is from the start of an application, and from there, everything should be fine, left alone ?


I am working on a project. But I have troubles defining where interfaces and classes (entities, value objects, implementations) should go (assemblies, namespace naming...).

Question 3 : Does DI imply a special structure for code organisation ?


I heard that domain/business layer should not reference any DI Framework.

Question 4 : Does that recommendation also apply to any other layer ? Or is it false ?


I am working with two libraries (say LibraryA and LibraryB). LibraryB contains three classes, ClassA, ClassB, ClassC. Each class depends on the previous (with ClassA being the root/aggregate). LibraryA depends on ClassA.

Question 5 : Is it better to create a factory inside LibraryB, dedicated in creating ClassA and its dependencies (using only new keyword), or would it be better to make full use of the DI framework, and manually register ClassA, ClassB, ClassC, and resolve ClassA ?

Community
  • 1
  • 1
David Khuu
  • 937
  • 3
  • 10
  • 21

2 Answers2

4

I should not use anymore the new keyword

It's all about the differences between newables and injectables. Yes, you should absolutely still use the new keyword, but not for services/injectables.

Does he imply that the only time the DI framework should be called (to resolve something) is from the start of an application

You need to resolve once per request. If your application handles a single request and dies (a console application for instance), this would mean you resolve once during startup. Most application types (web applications, web services, desktop applications, etc) however handle many requests (sometimes concurrently) and this means that that many 'root' objects will be resolved.

Doing a resolve per request (whatever 'request' might be in the context of that application) is important, because doing one single resolve for the complete app domain will create a single object graph and that means that this object graph should be thread-safe and reusable. You might be able to get this working but that is usually a lot of work and error prone. That's why DI containers often contain sophisticated ways of registering services with a certain scope (per web request, per WCF operation, etc).

Does DI imply a special structure for code organisation ?

No, it does not. DI doesn't force you into a certain organizational structure, but you will have to design classes using loose coupling and SOLID to gain the most benefit.

I heard that domain/business layer should not reference any DI Framework. Does that recommendation also apply to any other layer ? Or is it false ?

Yes, this advice holds for every part of the system, except your Composition Root. But please note that a layer doesn't equal an assembly. Take a look at this question and its answers.

Is it better to create a factory inside LibraryB

That's hard to answer without more information (you might want to start a new question for this), but in general you should only resolve one object per request and let the container built up the whole graph. If LibraryA uses ClassA in LibraryB, there will be one or multiple classes in LibraryA that depend on ClassA. So instead of resolving ClassA directly from the container, you should probably resolve one of the classes of LibraryA from the container -or recursively- one of their parents. For instance when you have an MVC application with an XController that depends on ClassD (from LibA) that depends on ClassA, in that case you should only resolve XController.

Community
  • 1
  • 1
Steven
  • 166,672
  • 24
  • 332
  • 435
  • Thank you for the answer. I read the article about newables and injectables. Basically, any class that is simple/composed of basic types/mainly a data object should be instantiated with new, and any class with behavior (methods) should be retrieved through the di framework ? I must admit that doing a factory for each newable class would lead to an explosion of plain creational classes. I wrote a last question (number 5). If you would like to answer it, I would greatly appreciate. – David Khuu Aug 14 '13 at 22:08
  • You don't need a factory for newables. You can just new them up in code. – Steven Aug 15 '13 at 04:12
  • I don't get it. In order to benefit the scope possibilities of the DI framework, I HAVE to use it from the inside of the layer (and therefore reference it) ! So, why should my layers NOT reference the di framework ? I am lost. Do you know any existing application, using a DI framework, that I could study ? – David Khuu Aug 15 '13 at 10:31
  • @DavidKhuu: No, you don't have to. You can (and should) only use this functionality from within your composition root. This can be achieved by implementing decorators or interceptors (implemented in the Composition Root) that implement an abstraction from the application and wrap the real implementation. – Steven Aug 15 '13 at 10:41
  • @DavidKhuu: If you want to know more about this, please create a new Stackoverflow question about this and add the link to it in a comment below. – Steven Aug 15 '13 at 10:50
2

Totally agree with Steven's answer, and regarding your fourth question:

Question 4 : Does that recommendation also apply to any other layer ? Or is it false ?

In Domain Driven Design, The Domain layer is considered as core of the application and other layers like UI, Database, Infrastructure layers are like add-on to it. That's why Domain layer will be the primary and not having reference to other layers. I hope this is what they mean by above statement. Please have a look at the graph given with question DDD: how the layers should be organized?.

For further reading I have a post on DI here.

Please let me know in case of further query. Thanks.

Answers to David's first comment:

Data Repositorys layer has repositories as per http://martinfowler.com/eaaCatalog/repository.html and http://msdn.microsoft.com/en-us/library/ff649690.aspx.

Mapping layer is supposed to have ORM (http://en.wikipedia.org/wiki/Object-relational_mapping) like Nhibernate or entity framework.

Data Repository and Mapping are part of DAL (data access layer) and those are optional patterns but most commonly used to access the data. If you are not having complex DAL...you can just use JDBC or ADO.NE here.

Further to understand how DI works in code...best place I found is the Ninject user Guide http://ninject.codeplex.com/wikipage?title=User%20Guide&referringTitle=Home, specially the Walkthrough given there.

Community
  • 1
  • 1
Praveen Prajapati
  • 969
  • 1
  • 16
  • 21
  • I read the articles you provided. I would love to apply some parts of the schema (http://stackoverflow.com/q/5881872/2671072) but there are two new layers, Data Repositories, and Mapping Layer. Where do they come from ? I can't also figure how the DI framework is supposed to work. Which layers can have a reference to the DI framework (using XXX), and use it (IoC.Resolve/Get) ? – David Khuu Aug 14 '13 at 22:32
  • @David I have added the answers to those to my answer above (as there is limit of characters in comment so I could not add that all here. Thanks.) – Praveen Prajapati Aug 15 '13 at 03:42
  • I read Ninject documentation. It lists how users can achieving resolution of objects, but examples are too simple. I can't manage to figure the big picture (the whole application). Do you know any functional application using a DI framework that I could study the entrails ? – David Khuu Aug 15 '13 at 09:58
  • You can download the code and run Project Silk available at http://silk.codeplex.com/. A sample application at http://microsoftnlayerapp.codeplex.com/ will also help here. Thanks. – Praveen Prajapati Aug 15 '13 at 11:08