Search code examples
dependency-injectiondecouplinglayer

Dependency Injection and decoupling of software layers


I am trying to implement Dependency Injection to make my app tester friendly. I have a rather basic doubt.

Data layer uses SqlConnection object to connect to a SQL server database. SqlConnection object is a dependency for data access layer. In accordance with the laws of dependency injection, we must not new() dependent objects, but rather accept them through constructor arguments. Not wanting to upset the DI gods, I dutifully create a constructor in my DAL that takes in SqlConnection.

Business layer calls DAL. Business layer must therefore, pass in SqlConnection. Presentation layer calls Business layer. Hence it too, must pass in SqlConnection to business layer.

This is great for class isolation and testability. But didn't we just couple the UI and Business layers to a specific implementation of the data layer which happens to use a relational database?

Why do the Presentation and Business layers need to know that the underlying data store is SQL? What if the app needs to support multiple data sources other than SQL server (such as XML files, Comma delimited files etc.) Furthermore, what if I add another object upon which my data layer is dependent on (say, a second database). Now, I have to modify the upper layers to pass in this new object.

How can I avoid this merry-go-round and reap all the benefits of DI without the pain?


Solution

  • Frankly what you should do is create a generic interface for accessing your data. A Repository, and then create a Sql Implementation of this interface, and dont inject your SqlConnection.

    This way in testing you just replace the SqlImplementation of the common interface with the Testing Implementation (mock) and off you go.

    I think you're drilling into the DI too far. In the case of a Sql Implementation you should possibly inject the connection string, but not the SqlConnection itself.