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

Tuesday, 26 May 2020

Implementing Repository + Dependency Injection in .Net core MVC with Entity framework core

In this blog I will create an application using .net Core MVC and Entity framework core implementing Repository pattern and Dependency Injection.

I will make the application loosely coupled as much as possible. Data access layer and UI will be completely independent of each other.

Prerequisite

Prior knowledge of MVC and Entity framework

Let’s begin

Project Creation

I am using visual studio 2019 community edition.
Open your IDE and create .net core MVC project



Select Asp.Net Core Web Application and press next


Name your solution and create


Project is created

The solution will have Controller, Model, View folder and one new wwwroot folder and few more files named appsetting.json, Startup.cs, Program.cs

Let’s understand what these files are?

Appsetting.json file is your web.config file
Program.cs file is same as in your console application and is called once for the entire application life cycle
Startup.cs is used for configuring your .net core application

Let us create a small module of adding product in Ecommerce website

Model

First create a Product model in, for that we will create a new .net core class library project in same solution

namespace ECommerce.Entity

{

    [Table("Product")]

    public class Product

    {

        [Key]

        public string ProductId { get; set;  }

        [Required]

        [MaxLength(50)]

        public string ProductName { get; set; }

        [MaxLength(300)]

        public string ProductDescription { get; set; }

        [Required]

        [DisplayName("Category")]

        public string CategoryId { get; set; }

        [Required]

        public double QuantityPerUnit { get; set; }

        [Required]

        public double UnitPrice { get; set; }

        [Required]

        public double MSRP { get; set; }

        public double AvailableSize { get; set; }

        public string AvailableColor { get; set; }

        public double Discount { get; set; }

        [Required]

        public double UnitWeight { get; set; }

        [Required]

        public double UnitsInStock { get; set; }

        public double UnitsOnOrder { get; set; }

        public double ProductAvailability { get; set; }

        public string Picture { get; set; }

        public string Note { get; set; }

    }

}

 

This model will be used to save data and bind view and controller.

 

Entity framework core Context

 

Next step is to create Entity framework core context. For that we create a new .net core class library project and install a nugget package in it.

Create a ECommerceContext class

public class ECommerceContext : DbContext

    {

        public ECommerceContext(DbContextOptions<ECommerceContext> options) : base(options)

        {

           

        }

 

        public DbSet<Product> Products { get; set; }

    } 

 

 

Repository

 

Now let’s create a new .net core class library project named Ecommerce.IRepositories

And create an interface in the project. This project will only contain Interfaces

 

public interface IProductRepository

    {

        IList<Product> GetProducts();

        Product GetProduct(string productId);

        void Add(Product product);

        Product Update(Product product);

        void Delete(Product product);

    }

Interfaces plays key roles in making application loosely coupled and more injectable more

 

To implement this interface we’ll create another .net core class library project for repository

Name Ecommerce.Repositories and create a class

 

public class ProductRepository : IProductRepository

    {

        private readonly ECommerceContext productContext;

        public ProductRepository(ECommerceContext context)

        {

            productContext = context;

        }

 

        public void Add(Product product)

        {

            product.ProductId = Guid.NewGuid().ToString();

            productContext.Add(product);

            productContext.SaveChanges();

        }

 

        public void Delete(Product product)

        {

            productContext.Products.Remove(product);

            productContext.SaveChanges();

        }

 

        public IList<Product> GetProducts()

        {

            return productContext.Products.ToList();

        }

 

        public Product GetProduct(string productId)

        {

            return productContext.Products.FirstOrDefault(x=> x.ProductId == productId);

        }

 

        public Product Update(Product productChanges)

        {

            var product = productContext.Products.Attach(productChanges);

            product.State = Microsoft.EntityFrameworkCore.EntityState.Modified;

            productContext.SaveChanges();

            return productChanges;

        }

    }

 

Now, we have created our context, our model and our repository.

 

Application

 

It’s time to create controller named ProductController.cs and inject all the dependency in it. To inject the dependencies we need to configure startup.cs file

 

Add following code in ConfigureService method

 

services.AddScoped<IProductRepository, ProductRepository>();

services.AddDbContextPool<ECommerceContext>(x => x.UseSqlServer(ConnectionString, b => b.MigrationsAssembly("ECommerce")));

controller will look like below code

IProductRepository productRepo = null;

public ProductController(IProductRepository prodRepo)

{

productRepo = prodRepo;

}

As you can see we are using parameterized constructor of controller to inject the dependency.

.net core there is a build in support for dependency injection

            services.AddScoped<IProductRepository, ProductRepository>();

Above line is used to inject any dependency in controller

Below method is used to save Product detail in database

public ActionResult SaveProduct(Product product)

        {

            int res = 3;

            if (ModelState.IsValid)

            {

                if (string.IsNullOrEmpty(product.ProductId))

                {

                    productRepo.Add(product);

                }

                else {

                    product = productRepo.Update(product);

                }

                res = 1;

            }

            else {

            }

            return View("Create");

        }

View to controller binding is same as it was in MVC application and I understand you guys are better at that so not going through with it

Notes

If you look at the Repository class, I have injected context class in its constructor.

Summary

This is how you create a .net core MVC application with Repository and dependency injection which is loosely coupled and easily configurable

 

I am open to all kind of discussion. Feel free to comment and suggest anything

Thank you.

 


Thursday, 16 April 2020

Dependency Injection in ASP.Net classes for TDD


Dependency Injection in ASP.Net classes for TDD

In Asp.Net classes there is not built in library like Unity or Autofac.

What’s the problem with plain c# classes?

The reason for that is, in MVC or Web API Controller objects are created via IHttpControllerActivator interface which is inherited by a class. In Unity library IDependencyResolver is user which is kind of a ServiceLocator anti-pattern hence objects of controllers are created without manual intervention
This IHttpControllerActivator lies in API pipeline to instantiate controllers
Now when we develop c# classes and code becomes too big and complicated and automatically becomes tightly coupled which makes TDD harder and next to impossible as once because there is no way to inject mock/test classes instead of actual DB or dll library classes

How to solve it?

We can create a ServiceLocator anti-pattern in plain old .net classes for DI purpose. Instead of directly creating object of third party dll library we can simply register those in ServiceLocator anti-pattern and then resolve the dependency within the scope of the anti-pattern

</>
       public class ServiceLocator
       {
              // Key = interface type
              // Value = concrete type that implements the Key interface
              private static readonly Dictionary<Type, ServiceTypeContainer> types;

              // used for locking, especially when creating objects using reflection
              private static object syncObject = new object();

                           static ServiceLocator()
              {
                     types = new Dictionary<Type, ServiceTypeContainer>();
                     Register<IDependency>(typeof(Dependency));
              }

              public static T Resolve<T>()
              {

                     ServiceTypeContainer typeContainer = types[typeof(T)];
                     T returnObj;

                     if (typeContainer.Initializer == null)
                     {
                           // CreateInstance uses a static cache that is not thread-safe
                           // We could change the lock to on typeContainer if this becomes a bottleneck
                           lock (syncObject)
                           {
                                  returnObj = (T)Activator.CreateInstance(typeContainer.ServiceType);
                           }
                     }
                     else
                     {
                           returnObj = (T)typeContainer.Initializer();
                     }

                     return returnObj;
              }

              public static void Register<T>(Type objT)
              {
                     Register<T>(objT, null);
              }

              public static void Register<T>(Type objT, ServiceInitializer initializer)
              {
                     types.Add(typeof(T), new ServiceTypeContainer(objT, initializer));
              }
       }

       public class ServiceTypeContainer
       {
              public Type ServiceType
              {
                     get;
                     private set;
              }

              public ServiceInitializer Initializer
              {
                     get;
                     private set;
              }

              public ServiceTypeContainer(Type serviceType, ServiceInitializer initializer)
              {
                     ServiceType = serviceType;
                     Initializer = initializer;
              }

       }

       public delegate object ServiceInitializer();

There are two classes above one is used to register classes and another type container
Now instead of tightly coupled code you can register all the third party dll classes in anti-pattern and then use it like with the interface only
As you can see I have registered the Dependency class using IDependency type and later I will resolve it using IDependency only

Practicle

Below is a class ProductHistoryClass which has parameterized constructor that takes a custom type as an argument which is in fact a reference to a service or a dll class calling another method

public class ProductHistoryClass
    {
        private IDependency dependency;

        public ProductHistoryClass(IDependency _dependency)
        {
            dependency = _dependency;
        }

        public int FindProductHistory()
        {
            return dependency.FindProductHistory();
        }
    }

Below are our dependency Interface and class
public interface IDependency
    {
        int FindProductHistory();
    }

public class Dependency : IDependency
    {
        public Dependency()
        {

        }

        public int FindProductHistory()
        {
            return 1;
        }
    }
I have kept declaration and definition simple to understand

Now in old ways we would be creating object of Dependency class and then pass the object into constructor calling of ProductHistoryClass which makes our classes tightly coupled and difficult to modify in future
So how to make use of anti-pattern here.

Don’t worry I got it covered J

In you calling class you can do like

public static void WithParam()
        {
            ProductHistoryClass prdCls = (ProductHistoryClass)Activator.CreateInstance(classType,ServiceLocator.Resolve<IDependency>());
            int res = prdCls.FindProductHistory();
        }

Here I have used reflection to create object or ProductHistoryClass and ServiceLocator to resolve our dependency

And just by these simple lines of code we are able to inject dependency in plain old c# classes
Now I would like you guys to experiment with this.
This is it from this blog hold tight till I write next one
J
If you like the blog then please like it and leave a comment
Do not forget to subscribe.
Thank you.

Send All Azure App Insights Or Logs Data To Tool Like Datadog

  Introduction Microsoft Azure provides a variety of insights and monitoring logs that you can monitor to check the state of a resource and ...