12

I am trying to wrap my head around the concept of Dependency Injection. I have a visual studio solution. I have split it into 3 projects: DataAccessLayer, ServiceLayer, BusinessLogicLayer.

The ServiceLayer acts as a link between BusinessLogic and DataAccess hiding things like SQL and LINQ statements from the BusinessLogic.

Now, many tutorials online recommends using DependencyInjection to use the classes in the ServiceLayer in my BusinessLayer. I believe, the reason is so that the BusinessLayer is loosely coupled with the ServiceLayer. I, however, do not fully understand how to implement this when these two layers (and their corresponding classes) are in different projects.

According to online tutorials, I will have my classes in ServiceLayer implement an Interface which is what will be referred to in my BusinessLayer. But which project should this interface be defined? It makes sense that this interface is defined in the ServiceLayer. But wouldn't having a reference to this interface from the BusinessLayer cause a tightly coupled logic between these projects? Would that take away the benefit of Dependency Injection?

I hope someone can give me a "Dependency Injection for Dummies" kind of answer for me explaining where my understanding is wrong. Thank you in advance :)

user3259937
  • 567
  • 7
  • 16
  • 1
    you are looking for the [Composition Root](http://stackoverflow.com/questions/6277771/what-is-a-composition-root-in-the-context-of-dependency-injection) which is the place to wire up your application, and will use all dlls from all layers. – Sam Holder May 10 '15 at 10:30
  • 2
    Take a look at the [stairway pattern](http://stackoverflow.com/questions/29259414/stairway-pattern-implementation). Basically you always have an interface project between two implementation projects, where both projects only "know" about the interface project but not (necessarily) about each other. Then, as @SamHolder said, in the composition root where you know about every project, you do the necessary "plumbing", i.e. resolving which implementation class to use for which interface. – Corak May 10 '15 at 10:38
  • Related: https://stackoverflow.com/questions/9501604/ioc-di-why-do-i-have-to-reference-all-layers-assemblies-in-entry-application – Steven May 10 '15 at 14:05

1 Answers1

8

Dependency Injection is a great thing, because it makes your code independent from implementations of other pieces of code. All dependencies should be injected via constructor(sometimes property) in which you only declare interfaces, not implementations.

In this case you are able for example to inject fake implementation to run unit tests. Also you are able to write multiple versions, for example you can support multiple databases with a common interface and according to user's choice you inject a proper implementation.

Now how to achieve it. You could extract interfaces to another project for example "Common". This would prevent you from adding references to implementations, where you don't need them. Then your BusinessLayer and ServiceLayer would reference to Common.

You'd have the following projects:

  • Common - interfaces for dependencies
  • ServiceLayer - has a reference to Common and implements those interfaces
  • BusinessLayer - has a reference to Common and uses those interfaces in constructors
  • Root - it can be for example a WPF application. It has references to all layers. There should be a mechanism which is able to create instances from BusinessLayer and inject proper implementations from ServiceLayer to them

You don't have to implement your own IoC and DependencyInjection. You could check out for example: Caliburn.Micro - I really like this framework.

Wojciech Kulik
  • 7,823
  • 6
  • 41
  • 67
  • @user3259937 does it answer your question? – Wojciech Kulik May 10 '15 at 16:38
  • Yep, it does. I will approach my problem the way you suggested. Thank you so much sir. – user3259937 May 11 '15 at 01:52
  • By giving the 'Root' (e.g. WPF application) access to all layers aren't you at risk of breaking separation of concerns though? A developer could (perhaps without knowing) make calls from the WPF application to the service layer (which the OP has indicated is 'behind' the business logic layer), although not mentioned in the answer assuming the DataAccessLayer is also referenced then code could be written directly calling this an bypassing all other layers too. – d219 Sep 28 '20 at 10:58
  • 1
    @d219 you always have to have some place which joins all layers together and has almost global knowledge, after all this is your application. It does not have to be Root, it could be a separate layer. If you prefer to join everything outside of the Root to avoid referencing ServiceLayer by Root, you can. There are no strict rules. You can even add another layer called DataAccessLayer which would be referenced only by ServiceLayer. It also depends on what you understand by Business layer and Service layer. All depends on specific case. But you should always try to separate things – Wojciech Kulik Sep 28 '20 at 11:10
  • Cheers - that's kind of the thought process I'm going through now; everything is joined outside of the root project, in a small project referenced by 'root' where it's clear that the reason for referencing everything else is for the sole purpose of performing the DI. – d219 Sep 28 '20 at 11:25