Dependency Inversion Principle is one of the five solid principles in software architecture design, Here you learn how to implement Dependency Injection in C# console application example.
Dependency injection is a design pattern, a technique that helps to inject dependent object of a class without changing the concrete implementation.
In this post, we learn how to implement dependency injection in c# console application, for .Net core version and earlier version using unitycontainer.
If you are already working with .net core application and implemented dependency injection with startup file, then you know how easy it was, here the challenge is, we do not have startup.cs file in our .net core console application.
Let’s look at how we can implement dependency inject in console application without having startup file, first add all required namespace like Microsoft.Extensions.DependencyInjection
in our program.cs file
First we create a host builder method that returns IHostBuilder, inside the method we have extension method "ConfigureServices" and service collection object, where we can add all our dependents class.
public static IHostBuilder CreateHostBuilder(string[] args) { var _hostBuilder = Host.CreateDefaultBuilder(args) .ConfigureServices((services) => { services.AddSingleton<MongoDBInfo>(); services.AddSingleton<DbService>(); services.AddLogging(); }); return _hostBuilder; }
Now, from main method, we call host = CreateHostBuilder(args).Build();
and then any service we want to consume like host.Services.GetService<DbService>();
// add following namespace using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Logging; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; public static void Main(string[] args) { Console.WriteLine("Hello World!"); var host = CreateHostBuilder(args).Build(); var _dbService = host.Services.GetService<DbService>(); var _result = _dbService.InsertData(); Console.WriteLine(_result.Result); } public static IHostBuilder CreateHostBuilder(string[] args) { var _hostBuilder = Host.CreateDefaultBuilder(args) .ConfigureServices((services) => { services.AddSingleton<MongoDBInfo>(); services.AddSingleton<DbService>(); services.AddLogging(); }); return _hostBuilder; }
in above dependency injection implementation I have implemented following DbService class, with one simple string method to test if DI working fine, It’s done! This piece of code was written in .net core 3.1 framework.
public class DbService { static MongoDBInfo _dbInfo = null; public DbService(MongoDBInfo dbinfo) { _dbInfo = dbinfo; } public async Task<string> InsertData() { string _result = "testing method call"; using (var session = await _mongoClient.StartSessionAsync()) { // code here } return _result; } }
Let's understand the Dependency injection with a real-time simple example.(This example is for .net earlier version 4.6)
Business:
We have a SportsCar class, we need to add a new sport car in database, so we have created a method AddCar() in all layer, just assume now we have SQL Database, in three tier architecture scenario how the normal implementation will be done!
Here in example we have created a console app (just to avoid button click in case of web / win app), so we can focus more on dependency injection using UnityContainer.
Step 1:
First we create data access layer with a simple add method, we have two data access class, one for SQL database and another for Oracle database
public interface IDataAccess { void AddCar(SportsCar s); } public class MSSQLDal : IDataAccess { public void AddCar(SportsCar c) { // database implementation here } } public class OracleDal : IDataAccess { public void AddCar(SportsCar c) { // database implementation here } }
Step 2:
Now create a simple SportsCar class with one property and one AddCar() method
public class SportsCar { public string CarType { get; set; } private IDataAccess dataAccess; public SportsCar(IDataAccess da) { dataAccess = da; } public void AddCar() { SportsCar c = new SportsCar(new MSSQLDal()); dataAccess.AddCar(c); } }
Step 3:
Now in Program class create a new instance of UnityContainer class.
You may need to add Microsoft.Practices.Unity
reference in your project,
either can add them manually or use NuGet Package to install and add them in your project.
using Microsoft.Practices.Unity; public class Program { static void Main(string[] args) { IUnityContainer iuContainer = new UnityContainer(); iuContainer.RegisterType<SportsCar>(); iuContainer.RegisterType<IDataAccess, MSSQLDal>(); // iuContainer.RegisterType<IDataAccess, OracleDal>(); SportsCar car = iuContainer.Resolve<SportsCar>(); car.CarType="McLaren 570S"; car.AddCar(); } }
SportsCar car = iuContainer.Resolve<SportsCar>();
Now suppose instead of using SQL Data access layer you want to use Oracle Data Access Layer, you just need to enable the line below.
iuContainer.RegisterType<IDataAccess, OracleDal>();
Hope you understood how to use Dependency injection using UnityContainer in C# .Net
You may be interested in following tutorials: