asp.net-mvc-4architectureinversion-of-controlmulti-tier

Asp.Net Multi-Tier Architecture Class Library References


I'm a PHP programmer that has applied for an ASP.NET job. They gave me an assignament to make an application (of my choice) that implements a multi-tier arhitecuture.

I have alot of dillemas. As I understand, multi-tier is a concept that doesn't have a universal form and everyone should decide what is best for them. However, they advised me that the presentation layer should not have any refferences to the data access layer, which makes sense. But...

I created a new project with Add new project (that has controllers and views) who is a presentation layer. Now, in the presentation layer, there is also a class library that uses Ninject to inject dependencies for the entire application called NinjectIoC. NinjectIoC has to have a refference to the presentation layer project in order to inject dependencies directly in the controller as an argument. It also has to have refferences to all the other layers (DataAcessLayer, BusinessLayer etc...) order to bind them to their dependencies.

The main problem is that presentation layer project has to also have a refference to the NinjectIoC to create the StandardKernel inside Global.asax which creates a cirucullar dependency and is not permitted.

The only solution is to add a refference to the presentation layer project of all the layers (including DataAccessLayer) which, as I understand, is a bad thing. But, that is the only way to bind all the interfaces of all the layers and execute it inside Global.asax.

Am I thinking wrong?

EDIT:

NinjectIoC has Ninject installed and has a refernce to all the layers in order to bind them across the application. It has to have a reference to the UI in order to be called in Global.asax

UI has to have a reference to NinjectIoC so it can call it in Global.asax for controller binding.

I tried to create an intermediary class library that has a reference to NinjectIoC. That library is referenced in the UI. The problem is that that also creates a circular dependency beacuse NinjectIoC has to have a reference of the UI in order to bind the controllers.


Solution

  • Multi-tier can simply mean that there is a DAL, a BL, and a UI Layer. And the requirement to "not reference the DAL in the UI Layer" can simply mean that your UI layer (MVC4 app) can only reference the BL. This is simple to achieve, for example like this:

    This is the classical, most simple, multi-layered project.

    In the final compilation, of course, the indirect dependencies will include the UI project and the 3 libraries, but you don't need to add a reference to the DAL in the UI.

    Another different question is using the IoC pattern. In this case, to solve the circular references problem, I recommend you to define separately projects of "Interfaces" and projects of "Implementations" for each layer. Something similar to the previous structurem, but with this changes:

    You need to define which is the main project. It's usually the UI project. This project is the one that will have all the dependencies.

    In this case, the UI project depends directly on the BL Interfaces project. And the BL Interfaces will depend on the DAL Interfaces. In a few words, your UI project will only have direct dependencies with the BL Interfaces.

    The question is that, when you try to run the code, it will need to solve this dependencies, i.e. find the implementation of the interfaces, and there dependencies. This is the "compositio root" of your application, and it's where you need to register the dependencies. I.e, this is the place where you need to define which concrete implementation will be use for each interface. And, if this implementation depends on other interfaces, you have also to define their implementations. Depending on the framework (I don't know if you can do it with NInject) you can do this dynamically, without the need to add references to the implementation projects. However, even if you have to include references to all the other implementation and interfaces projects you'll have not circular dependencies, and your UI will have not dependencies on the DAL or implementation layers. You only need them for registering them in the IoC Container, which is a very different question. (If you use constructor injection, you get the maximum possible decopuling using this project structure).

    Keeping one or several separated entities projects allows you to avoid circular references, and direct dependencies between project. For example, if you defined the entities in your DAL project, nad you use them in your UI project you'd need to add a reference to the DAL project. This problem dissapears if the entities are declared in a separate project.

    The pure IoC, like the "Onion Architecture" goes far beyond this by defining the entities and necessary interfaces of dependencies in the main project (UI project), then implementing these dependencies in other projects, and solve them dynamically, to avoid circular references. I.e. all the other projects depend directly or indirectly on the UI project, and not the other way round. In this case you need to solve the dependencies dynamically to avoid the circular references.

    As you can see there are many options, and I've shown you several examples of working solutions.