Dependency Injection in "WCF Service Library" Project with Self hosting


πŸ‘‰There are several contents available on the internet that talk about injecting dependencies through .svc file's markup [in WCF service application] and it's easy when you have a WCF service application. But, it is equally easy to do that even in your WCF Library project (without .svc)

I've originally posted this article on CodeProject.com, you can refer it here

Introduction

There are many ways to make your application loosely-coupled. Using Dependency injection is one such way. Loosely coupled application helps you in making your application maintainable, extensible and it also helps in testing your code, etc. This article will walk you through step by step into implementing IOC container into your WCF service library project. Finally, we are going to add the self hosting component. Here, we are going to use Autofac as the IOC Container.

Background

For making application loosely coupled, it should adhere to the decorum of SOLID principles in object oriented programming.
  • Single responsibility principle: A class should only have a single responsibility, that is, only changes to one part of the software's specification should be able to affect the specification of the class.
  • Open–closed principle: "Software entities ... should be open for extension, but closed for modification."
  • Liskov substitution principle: "Objects in a program should be replaceable with instances of their subtypes without altering the correctness of that program."
  • Interface segregation principle: "Many client-specific interfaces are better than one general-purpose interface."
  • Dependency inversion principle: One should "depend upon abstractions, [not] concretions."
Dependency injection helps in attaining 'Dependency Inversion Principle'
Sourcehttps://en.wikipedia.org/wiki/SOLID

For IOC Container, we are going to use Autofac and Autofac.WCF
Sourcehttps://autofaccn.readthedocs.io/en/latest/integration/wcf.html

Things required

  1. Visual Studio (I am using VS Community Edition 2017)
  2. Autofac
  3. Autofac.WCF
  4. And some time to spare:)

Let's get started 

I am going to use very simple code as an example. My focus is on making things simple to understand.
Step 1: Create a Solution and Add WCF Library Project



We'll name the solution as "DependencyInjectionWcfWithSelfHosting" and the WCF service library project as "TestService".

Step 2: Add Scaffolding Code in WCF Service Project
Remove app.config, and the system created IService1Service1.cs file (You can rename these files but I like to start with a clean slate)

πŸ‘‰ Remove app.config, and the system created IService1, Service1.cs file (You can rename these files but I like to start with a clean slate):


πŸ‘‰ Right click on your TestService project and add new item as a WCF Service class and name it as "DisplayService".


It should look like this:

IDisplayService.cs

DisplayService.cs


πŸ‘‰As you can see, there is nothing fancy in code, just an input passed is return back as is. 
But, hold on a minute, we can do something that would decorate that input with some string message, say for an example:

πŸ‘‰If I pass "Sunny" as an input, I can add some prefix string to it as "You've entered" to the passed input and return it as "You've entered Sunny".

πŸ‘‰Well, I can simply append input string with "You've entered" and return it from DisplayInputValue().

But, to get around the topic of Dependency Injection in Wcf Service, We will try to do the appending part from some utility classes and then, inject its instance through Constructor Injection.

Step 3: Add Just Enough Code for Utility Class


πŸ‘‰Add folder name "Utilities" in TestService project and add a class in it with name as "StringMixer" with the following code:


πŸ‘‰Extract interface from the "StringMixer" class. That would be "IStringMixer". This will help us during constructor injection into our "DisplayService"




We are going to make use of these utilities in a moment.

Step 4: Add Hosting Support
πŸ‘‰ Add the console application to the solution and name it as "Host".


πŸ‘‰Go to the program.cs in console application and add the following code in Main(). Make sure you've added reference for "TestService" and "System.ServiceModel".
πŸ‘‰Now there might be an app.config file in the console application we've recently added. Add the following ServiceModel section in it.


✋ Or Alternatively

If you want, you can manually create your own service model configuration by right clicking on app.config and click on "Edit WCF Configuration" and do as suggested in its wizard (make sure it will run).

πŸ‘‰ Run your "Host" Application to make sure everything works

πŸ‘‰ You might get the access permission error, simply run your Visual Studio in administrator mode and then run your Host application

If you managed to get so far, congratulations. you are halfway done !! πŸ’₯

Step 5: Verify What We We've Done So Far Is Working or Not

πŸ‘‰ Try to open the url "http://localhost/TestService" in your WCFTestClient and make sure it works.



Step 6: Complete the Unfinished Business


As I mentioned at the end of point 3, we are going to inject the utility class "StringMixer" in the "DisplayService" as a constructor injection.

πŸ‘‰ Get to the "TestService" project, open your display service class and add a constructor.

πŸ‘‰ Inject the dependency of StringMixer using its interface as an abstraction, i.e., "IStringMixer".


DisplayService.cs now might look like this:


We are going to inject this dependency from the host application. Let's get started for an exciting adventure.

Step 7: Setup Autofac and Autofac.Wcf in "Host" Project

πŸ‘‰ Add "Autofac" and "Autofac.Wcf" as a nuget package in "Host" project:


πŸ‘‰ Add class in "Host" project with name "Bootstrapper". In this class, we will register our dependencies in Autofac container.


πŸ‘‰ It's like whenever Autofac sees the reference to those dependencies during constructor injection based upon their abstraction (interfaces), It will inject their registered class into it.

For example

"builder.Register(c => new StringMixer()).As<IStringMixer>();"

means, wherever there is a reference about IStringMixer, Autofac will inject StringMixer as its implementation.

Step 8: Tweak "Host" Project - A Little

Modify code in program.cs file by adding the following code in it:


Step 9: Run the Host Application. This Time, You've Got the Powers of Dependency Injection.

πŸ‘‰ Thank you for your patience. We are done walking those steps !!

(Image Courtesy: daniel-cheung from unsplash)

Github 

The complete code is posted on github and can be found at

Point Of Interest

πŸ‘‰ You can remove the app.config file from "Host" project and write the code related to EndPoint configuration in your host application instead. Just for information, I've added support for "http" and "netNamedPipe".

πŸ‘‰ You can also make use of the information provided in this article in WAS hosting as well.

πŸ‘‰ You can use any IOC container apart from Autofac or can make one of your own for dependency injection.

πŸ‘‰ It's not always necessary to have an interface for your class, But it gives better abstraction and composition over inheritance. Though, there are certain ways to Inject dependency for such class (I mean class without interface) using IOC Container.

References
πŸ‘‰ Dependency injection helps in attaining 'Dependency Inversion Principle'

πŸ‘‰ For IOC Container, we are going to use Autofac and Autofac.WCF 

Comments