2

I'm developing an ASP.NET MVC application. At the same time, I'm following the book "Dependency Injection in .NET" from Mark Seemann. My solution has one Data Access layer, a Domain layer, and the Web application project. Chapter two of the book says that I should put my controllers and viewmodels in a separate Presentation layer, which is what I'm trying to do right now.

Things are going ok. My goal is to build this app with DI in mind. My web app only references the Domain layer, the Data layer only references the Domain layer. Everything is as decoupled as I can possibly make it.

However, my web application project uses Ninject as the container, and in one class called NinjectWebCommon, I have to register one of my types as follows:

kernel.Bind<ITransactionRepository>().To<TransactionRepository>();

As you can see, I now have to reference TransactionRepository which is in my Data layer. Is it ok that my web application references the Data layer? Should it? Or is there another solution to prevent this coupling? Should I move NinjectWebCommon to the Presentation layer? I'm not sure what is best practice in this case. Unfortunately the book does not go too much into detail when it comes to this Presentation layer in an ASP.NET MVC application.

Ray
  • 4,679
  • 10
  • 46
  • 92

1 Answers1

4

Yes - this is fine. Your composition root needs a reference to everything it will work with. How else would it resolve abstractions?

There is a semantic difference between a project reference and a dependency here.

A reference is something your DI container will have to have in order to do it's job - you can't avoid that.

You avoid dependency by not writing your presentation layer code to depend upon concrete implementations of your data layer - only abstractions in your domain layer.

Put differently, a reference is a required element of the configuration, while a dependency is a choice by your implementation to depend on something.

Consider some MVC controller

public class SomeController 
{ 
    private ISomeRepository repository; 
    public SomeController(ISomeRepository repository) 
    { 
        this.repository = repository; 
    }

    // ... 
}

This controller has a dependency on the domain layer, which is expected. Contrast that to:

public class SomeController 
{ 
    private SomeRepository repository; 
    public SomeController(SomeRepository repository) 
    { 
        this.repository = repository; 
    }

    // ... 
}

This implementation has a hard dependency on the data layer, which is undesired.

jdphenix
  • 15,022
  • 3
  • 41
  • 74