2

I have a solution :

solution

  • Business have a reference to Business.Interfaces, DataAccess.Interfaces and Factory (for resolve IDataAccess in DataAccess.Interfaces)
  • MainProject have a reference to Business.Interfaces and Factory (for resolve IBusiness in Business.Interfaces)

My factory project use Unity for resolve dependencies. This project must have a reference to all others project except MainProject to access to constructors of concrete class and do mapping between class and interfaces.

But I don't add a reference to Business in Factory project because Visual Studio says to me :

A reference to Business could not be added. Adding this project as a reference would cause a circular dependency

How to resolve this ?

NightOwl888
  • 55,572
  • 24
  • 139
  • 212
  • I am not well familiar with Unity, but I think you should have the configurations (the registration of the classes) in the relevant project, not all in one project. – elirandav Feb 05 '17 at 22:23

2 Answers2

2

One way would be to reorganise your project a little bit.

I would get rid of the Factory project completely. If all you do is to resolve dependencies then you can do that in your MainProject since this is the only one which will need to know how to map things. Business shouldn't care about any concrete implementations, assuming all it does is to implement your business logic. Let it work with abstractions only, not concrete classes.

So in short, Business has dependencies on Interfaces projects only, Factory gone and all Unity mapping is done in MainProject. The MainProject is the only one which references all the other projects.

NightOwl888
  • 55,572
  • 24
  • 139
  • 212
Andrei Dragotoniu
  • 6,155
  • 3
  • 18
  • 32
2

As @Andrei pointed out, when configuring an application to use DI, the application should be responsible for wiring up all of its dependencies in its Composition Root.

A Composition Root is a (preferably) unique location in an application where modules are composed together.

Furthermore, the composition root should not be moved to an external library. Think of the composition root as a modern code replacement for a .config file. It is the application that is responsible for loading it and providing its contents to the dependent assemblies - the same is true for the Composition Root.

It is the Composition Root's job to push the dependencies down into the rest of the application. The dependent assemblies should not try to pull their own dependencies. It's called the Hollywood principle - "Don't call us, we'll call you". That said, it is also common to use the abstract factory pattern in conjunction with DI.

See this answer for a good visual representation of how it should work. Your application looks a lot like the first image - you should aim to make it like the second one. The application is logically setup in separate layers that depend on each other, but it is physically very flat.

NightOwl888
  • 55,572
  • 24
  • 139
  • 212
  • Thanks for your very comprehensive answer. I use now a configuration file in my main project for describe the mapping between concrete class and interfaces. And it's my main project that has all references to other projects. `Factory` project read unity section in configuration and resolve dependency using `Unity`. –  Feb 06 '17 at 07:49
  • Oh, no that is not what I meant. Don't *actually* put your configuration into a `.config` file. That is an antiquated way to do DI (in fact, many containers have dropped support for it) - XML configuration is not type safe and is very brittle compared to configuring the container in code. But treat that code as if it *were* a `.config` file for the application. – NightOwl888 Feb 06 '17 at 08:09
  • Hum ok so how to do this actually ? My main project have a unityconfiguration.xml file with mapping between class and interfaces. My main project have also all references to others projects. How to change this ? My factory project doesn't have a reference to others projects and I don't want to add reference in this project. This project read configuration and resolve only dependencies –  Feb 06 '17 at 08:14
  • That is the situation that DI is made to avoid :). Read [this answer](http://stackoverflow.com/a/9503612/181087) again. You should make a section near the start of the launch of the `MainApplication` (inside of that application) with a composition root to configure DI. Your `MainApplication` can and ***should*** reference all of the dependent libraries, because it is that application that is responsible for composing them together. You [*never* should reuse the composition root](http://blog.ploeh.dk/2015/01/06/composition-root-reuse/), so there is no point in putting it in a library. – NightOwl888 Feb 06 '17 at 08:48
  • Your "factory project" sounds a bit smelly to me. If you have factories that inject runtime instances, I suggest you [read this](https://www.cuttingedge.it/blogs/steven/pivot/entry.php?id=99). If you have enough factories to fill a library, then it sounds like there is something wrong with the design (maybe not, but it could be the case). You should probably aim to eliminate that library. – NightOwl888 Feb 06 '17 at 08:53