Showing posts with label Dependency Injection. Show all posts
Showing posts with label Dependency Injection. Show all posts

Friday, 12 November 2021

Use multiple implementations of an interface with ASP.NET Core DI

 On my previous article Middleware and Filters power in ASP.NET Core, one of my friend requested me to write about multiple implementations of an interface dependency resolution and I promised him that my next article will cove this. So here it is.

In this article, I’ll be using the same example by extending it to use multiple implementation of logger service by resolving it based on a config setting to log my exception.

First we will create ILoggerService and different implementation of it by creating a Services folder in the project.

namespace CoreWebAPIDemo.Services
{
public enum LogType
{
Trace,
Debug,
Information,
Warning,
Error
}
public interface ILoggerService
{
public void Log(LogType logType, object logInfo);
}
public class NullLoggerService : ILoggerService
{
public void Log(LogType logType, object logInfo)
{
//Do Nothing
}
}
public class SerilogFileLoggerService : ILoggerService
{
public void Log(LogType logType, object logInfo)
{
//your logging code
}
}
public class DbLoggerService : ILoggerService
{
public void Log(LogType logType, object logInfo)
{
//your logging code
}
}
}

Next, I’ll add a delegate to hold a reference of a function which accept the one string argument ‘logger type’ and return the ILoggerService instance. For this create a cs file “LoggerServiceResolver.cs” and add below code.

namespace CoreWebAPIDemo.Services
{
public delegate ILoggerService LoggerServiceResolver(string loggerType);
}

Now in Startup.ConfigureServices method, add the different logger services and also add LoggerServiceResolver with an implementation to find the right requested service.

services.AddScoped<SerilogFileLoggerService>();
services.AddScoped<DbLoggerService>();
services.AddScoped<NullLoggerService>();
services.AddTransient<LoggerServiceResolver>(serviceProvider => loggerType =>
{
switch (loggerType)
{
case "SerilogFileLogger":
return serviceProvider.GetService<SerilogFileLoggerService>();
case "DbLogger":
return serviceProvider.GetService<DbLoggerService>();
default:
return serviceProvider.GetService<NullLoggerService>();
}
});

I want to set the logger type option configurable through appsettings.json file so will add a setting there as:

{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"UserLogger": "SerilogFileLogger",
"AllowedHosts": "*"
}

By this implementation is ready. Now we need to add the code to consume this and for that I’ll enhance my “ExceptionHandlingMiddleware” which I use in my previous article. Please read it here: Middleware and Filters power in ASP.NET Core

using CoreWebAPIDemo.Services;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Configuration;
using System;
using System.Net;
using System.Threading.Tasks;
namespace CoreWebAPIDemo.Middleware
{
public class ExceptionHandlingMiddleware
{
private readonly LoggerServiceResolver _serviceResolver;
private readonly IConfiguration _configuration;
private readonly RequestDelegate _requestDelegate;public ExceptionHandlingMiddleware(RequestDelegate requestDelegate, IConfiguration configuraiton, LoggerServiceResolver serviceResolver)
{
_requestDelegate = requestDelegate;
_serviceResolver = serviceResolver;
_configuration = configuraiton;

}
public async Task Invoke(HttpContext context)
{
try
{
await _requestDelegate(context);
}
catch (Exception ex)
{
await HandleException(context, ex);
}
}
private Task HandleException(HttpContext context, Exception ex)
{
var logType = _configuration.GetValue<string>("UserLogger");
var myLogger = _serviceResolver(logType);
myLogger.Log(LogType.Error, ex);

context.Response.ContentType = "application/json";
context.Response.StatusCode = (int)HttpStatusCode.InternalServerError;
return context.Response.WriteAsync(ex.Message);
}
}
}

In above code, Code in Bold is the new code added and needed for this example. Now we all set to use the different implementations of ILoggerService with ASP.NET Core DI with my middleware. Similarly we can implement the same with “ExceptionHandlerFilter” class and changes would be (highlighted in Bold):

using CoreWebAPIDemo.Services;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.Extensions.Configuration;
using System;
using System.Net;
namespace CoreWebAPIDemo.Middleware
{
public class ExceptionHandlerFilter : Attribute, IActionFilter
{
private readonly LoggerServiceResolver _serviceResolver;
private readonly IConfiguration _configuration;
public ExceptionHandlerFilter(IConfiguration configuraiton, LoggerServiceResolver serviceResolver)
{
_serviceResolver = serviceResolver;
_configuration = configuraiton;
}
public void OnActionExecuting(ActionExecutingContext context) { }public void OnActionExecuted(ActionExecutedContext context)
{
var logType = _configuration.GetValue<string>("UserLogger");
var myLogger = _serviceResolver(logType);


if (context.Exception is Exception exception)
{
myLogger.Log(LogType.Error, exception);
context.Result = new ObjectResult(exception.Message)
{
StatusCode = (int)HttpStatusCode.InternalServerError,
};
context.ExceptionHandled = true;
}
}
}
public class HttpResponseException : Exception
{
public int Status { get; set; } = 500;
public object Value { get; set; }
}
}

Thank you for reading. Hope you enjoyed it and learn the Use of multiple implementations of an interface with ASP.NET Core DI. Don’t forget to clap if you like it and follow me to receive such article updates from me.

Wednesday, 10 June 2015

Dependency Injection with AngularJS Services

Hello Frnds,

Today we are going to discuss about dependency injection with AngularJS Services. It sounds interesting, Isn't it?

This post is the continuation of my previous post " CRUD with AngularJS and ASP.Net Web API".
So in case if you have not gone through that I would suggest please go through that.

What is Dependency Injection(DI):
In short & simple, It's a way to inject the dependencies. 
In detail, dependency injection is a software design pattern that implements inversion of control for software libraries. Caller delegates to an external framework the control flow of discovering and importing a service or software module specified or "injected" by the caller (source: http://en.wikipedia.org/wiki/Dependency_injection).

Dependency Injection is available through out the AngularJS. You can use it with Services, directives, filters, and animations etc. 
For more detail refer this: https://docs.angularjs.org/guide/di#



As I said DI can be used with services, So here I am going to explain you how you inject a service within a service. I am gonna use the same example here which I have used in my last post. In order to proceed I am going to do some changes in the example (used in previous post):
Change 1: Small change in our business model class "Book".
public class Book
    {
        public string Id { get; set; }
        public string Name { get; set; }
        public string Author { get; set; }
        public decimal Price { get; set; }
        public decimal OfferPrice { get; set; } //This is new property which we are adding.
    }

Change2: Define a new AngularJS service class, by adding a new script file "BookngDiscountService.js" under Scripts=>BookngScripts folder.

app.service('bookDiscountManageService', function () {
    this.getDiscountOnBook = getDiscountOnBook = function (bookPrice) {
        if (bookPrice >= 500) {
            return bookPrice * 10 / 100;
        }
        else {
            return 0;
        }
    }
});

What this service does is, it defines a service method to decide discount based on some logic on MRP of book. Very simple isn't it?



Change 3: Modify the view to accommodate to show Price after discount (let's call it OfferPrice).
<table style="border: solid 2px Black; padding: 5px;">
                    <tr style="height: 30px; background-color:lightsteelblue; color: maroon;">
                        <th></th>
                        <th style="width:50px">ID</th>
                        <th style="width:150px">Name</th>
                        <th style="width:150px">Author</th>
                        <th style="width:100px">MRP Price</th>
                        <th style="width:100px">Offer Price</th>
                        <th style="width:50px"></th>
                        <th style="width:50px"></th>
                    </tr>
                    <tbody ng-repeat="book in Books">
                        <tr>
                            <td></td>
                            <td style="width:50px"><span>{{book.Id}}</span></td>
                            <td style="width:150px"><span>{{book.Name}}</span></td>
                            <td style="width:150px"><span>{{book.Author}}</span></td>
                            <td style="width:100px"><span>{{book.Price | currency}}</span></td>
                            <td style="width:100px"><span>{{book.OfferPrice | currency}}</span></td>
                            <td>
                                <input type="button" id="Edit" value="Edit" ng-click="get(book)" />
                            </td>

                            <td>
                                <input type="button" id="Delete" value="Delete" ng-click="delete(book)" />
                            </td>
                        </tr>
                    </tbody>
                </table> 

Change 4: I am going to inject my new service (bookDiscountManageService, defined in change step 3) to my existing service called "bookManageService" (defined in earlier post, BookngService.js).
So here is change we need to do in "bookManageService" to inject our new bookDiscountManageService into bookManageService service.
app.service('bookManageService', function ($http, bookDiscountManageService) {
....
....
}

Highlighted piece of code in above line is the change, and it means that our bookManageService is dependent on another service bookDiscountManageService which is being injected to this service.



Now I want to use the service method 'getDiscountOnBook' of bookDiscountManageService service to update OfferPrice of the book by calling it inside 'getAllBook' service method of 'bookManageService' service. This how we need to modify the code:
//Fetch All Books
    this.getAllBook = function () {
        return $http.get("/api/BookAPI").success(function (data) {
            $.each(data, function (i, item) {
                item.OfferPrice = item.Price - bookDiscountManageService.getDiscountOnBook(item.Price);
            });
        })
    }

Highlighted piece of code shows the change part. What it means is, After getting data from ASP.NET Web API, it calls the injected service 'bookDiscountManageService' to calculate the discounted price.

This is it. Now think about it How easy to achieve the dynamics of OfferPrice without doing any change in ASP.NET Web API or AngularJS controller or in the main AngularJS service. 

After this change here is UI which you will get:
Thank You for reading. Don't forget to like it and feel free to give your feedback/comment.



Saturday, 23 February 2013

ASP.NET MVC 3 Dependency Injection using Unity.MVC3


ASP.NET MVC 3 Dependency Injection
Dependency injection (DI) is a design pattern and it is based on separating component behaviour from dependency resolution without object intervention. In other words we can say it removes the tightly coupled dependency between objects and components in collaboration model where there are contributors and consumers.
To know more about Dependency Injection Pattern, Please follow below links:
http://msdn.microsoft.com/en-us/magazine/cc163739.aspx
Dependency Injection is a particular implementation of Inversion of Control (IoC) principle, which says, An Object should not create other object in which they rely. It means the consumer object receives his dependencies inside constructor properties or arguments.
The advantages of using Dependency Injection pattern and Inversion of Control are:
·         Reduces class coupling
·         Increases code reusing
·         Improves code maintainability
·         Improves application testing

In ASP.Net MVC framework we need Dependency Injection to remove dependency between consumer (say controller) and contributors (service/business layer object).

Now let’s move on Implementation of Dependency Injection in ASP.Net MVC 3. Here we will talk about using Dependency Injection inside an MVC controller. We can also use Dependency Injection inside MVC View and MVC Action Filter.

I assume, you already have the knowledge regarding ASP.Net MVC3.
Before starting first thing we have to do is, IoC container which basically create dependency resolver per HTTP request. And I feel let’s not do that as there are lot many open sources available which provides library to do this like Ninject, Unity and so on.

Here I am going to use Unity.MVC3 and will show you, How you can use Dependency Injection inside controller using Unity.MVC3 IoC library. We will discuss to perform CRUD operation

Introduction of Unity.MVC3:
 A library that allows simple Integration of Microsoft's Unity IoC container with ASP.NET MVC 3. This project includes a bespoke Dependency Resolver that creates a child container per HTTP request and disposes of all registered IDisposable instances at the end of the request.

How to get this library: To include this on project, Right click on your MVC3 app solution in visual studio and click on “Manage NuGet Packages” and search of Unity (refer below pic).

Here you have select Unity.MVC3 (Highlighted on) click to install. Once you installed this you can see below highlighted (in pic) dlls reference in your project:

Next step we will create a service(with interface and implementation)  which is basically responsible to communicate with DB.

And then we create the actual service class which perform all my CRUD operation to create, delete, edit and modify user details to the DB.

Now we will create a controller factory class for Unity which implements IControllerFactory interface, extending CreateController and ReleaseController methods to work with Unity. This factory will create the instances of the controllers that work with Dependency Injection.
Note:
A controller factory is an implementation of the IControllerFactory interface, which is responsible both for locating a controller type and for instantiating an instance of that controller type.
The following implementation of CreateController finds the controller by name inside the Unity container and returns an instance if it was found. Otherwise, it delegates the creation of the controller to an inner factory. One of the advantages of this logic is that controllers can be registered by name.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using Microsoft.Practices.Unity;

namespace MyMVC3WebApp.Factories
{
    public class UnityControllerFactory: IControllerFactory
    {
        private IUnityContainer unityContainer;
        private IControllerFactory defaultInnerFactory;

        public UnityControllerFactory(IUnityContainer container)
            : this(container, new DefaultControllerFactory())
        {
        }

        protected UnityControllerFactory(IUnityContainer container, IControllerFactory innerFactory)
        {
            unityContainer = container;
            defaultInnerFactory = innerFactory;
        }

        public IController CreateController(System.Web.Routing.RequestContext requestContext, string controllerName)
        {
            try
            {
                return unityContainer.Resolve<IController>(controllerName);
            }
            catch (Exception ex)
            {
                return defaultInnerFactory.CreateController(requestContext, controllerName);
            }
        }

        public System.Web.SessionState.SessionStateBehavior GetControllerSessionBehavior(System.Web.Routing.RequestContext requestContext, string controllerName)
        {
            return System.Web.SessionState.SessionStateBehavior.Default;
        }

        public void ReleaseController(IController controller)
        {
            unityContainer.Teardown(controller);
        }
    }
}


Now next steps we have to register this Unity Library. While installing Unity.MVC3 you have observed, there is class called Bootstrapper.cs is been added to the solution including above mentioned dlls (shown in below pic, highlighted one).

Now next step we have to register our service Type inside BuilUnityController method present under Bootstrapper class.

Highlighted code in above pic is to register our service.

And the last step we have to do is, call the Initialize method of the Bootstrapper class from the global.asax.cs file. Shown in below pic

Now we have done with the create part and will see how I am using this inside my controller.
      
Now if you see, controller receives the business object through constructor and use this to perform CRUD operation. So here our controller is no more depended on creation object of service class on which it relays.

Please feel free to give your suggestion/feedback.

Thank You for reading this.  

References: