Home > Enterprise >  Error while creating Dependency Injection on ASP.NET Core 6.0 MVC
Error while creating Dependency Injection on ASP.NET Core 6.0 MVC

Time:04-11

I am doing chat app, and it was working before I start to create 3 layers layout (controller, service and repository) with dependency injection.

This was the format before I started to change to 3 layer layout, data access in controller:

using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Rendering;
using Microsoft.EntityFrameworkCore;
using ChatApplication.Data;
using MyWebChatApp.Models;
using Microsoft.AspNetCore.Authorization;

namespace ChatApplication.Controllers
{
    [Authorize]
    public class MessageController : Controller
    {
        private readonly ApplicationDbContext _context;

        public MessageController(ApplicationDbContext context)
        {
            _context = context;
        }

        // GET: Message
        public async Task<IActionResult> Index()
        {
            return View(await _context.Message.ToListAsync());
        }

This is the error I am getting, I tried to put in layers but I am getting that error:

An error occurred while starting the application.
AggregateException: Some services are not able to be constructed (Error while validating the service descriptor 'ServiceType: Repositories.Contracts.IRepository`1[Repositories.Models.Message] Lifetime: Singleton ImplementationType: Repositories.Repositories.MessageRepository': Unable to resolve service for type 'Repositories.Data.ApplicationDbContext' while attempting to activate 'Repositories.Repositories.MessageRepository'.) (Error while validating the service descriptor 'ServiceType: Services.Services.interfaces.IMessageService Lifetime: Singleton ImplementationType: Services.Services.MessageService': Unable to resolve service for type 'Repositories.Data.ApplicationDbContext' while attempting to activate 'Repositories.Repositories.MessageRepository'.) Microsoft.Extensions.DependencyInjection.ServiceProvider..ctor(ICollection serviceDescriptors, ServiceProviderOptions options)

InvalidOperationException: Error while validating the service descriptor 'ServiceType: Repositories.Contracts.IRepository`1[Repositories.Models.Message] Lifetime: Singleton ImplementationType: Repositories.Repositories.MessageRepository': Unable to resolve service for type 'Repositories.Data.ApplicationDbContext' while attempting to activate 'Repositories.Repositories.MessageRepository'. Microsoft.Extensions.DependencyInjection.ServiceProvider.ValidateService(ServiceDescriptor descriptor)

This is the code I made trying to put in 3 layers:

Program.cs

using Microsoft.AspNetCore.Identity;
using Microsoft.EntityFrameworkCore;
using ChatApplication.Data;
using Repositories.Contracts;
using Repositories.Models;
using Repositories.Repositories;
using Services.Services.interfaces;
using Services.Services;

var builder = WebApplication.CreateBuilder(args);

// Add services to the container.
var connectionString = builder.Configuration.GetConnectionString("DefaultConnection");
builder.Services.AddDbContext<ApplicationDbContext>(options =>
    options.UseSqlite(connectionString));
builder.Services.AddSingleton<IRepository<Message>, MessageRepository>();
builder.Services.AddSingleton<IMessageService, MessageService>();
builder.Services.AddDatabaseDeveloperPageExceptionFilter();

builder.Services.AddDefaultIdentity<IdentityUser>(options => options.SignIn.RequireConfirmedAccount = true)
    .AddEntityFrameworkStores<ApplicationDbContext>();

builder.Services.AddControllersWithViews();

var app = builder.Build();

// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
    app.UseMigrationsEndPoint();
}
else
{
    app.UseExceptionHandler("/Home/Error");
    // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
    app.UseHsts();
}

MessageController

#nullable disable
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Rendering;
using Microsoft.EntityFrameworkCore;
using ChatApplication.Data;
using Microsoft.AspNetCore.Authorization;
using Services.Services.interfaces;
using Repositories.Models;

namespace ChatApplication.Controllers
{
    [Authorize]
    public class MessageController : Controller
    {
        private readonly IMessageService _messageService;

        public MessageController(IMessageService messageService)
        {
            this._messageService = messageService;
        }

        // GET: Message
        public async Task<IActionResult> Index()
        {
            return View(await _messageService.GetChatMessages());
        }
    }
}

MessageService

using Repositories.Contracts;
using Repositories.Models;
using Services.Services.interfaces;

namespace Services.Services
{
    public class MessageService : IMessageService
    {
        public readonly IRepository<Message> messageRepository;

        public MessageService(IRepository<Message> repository)
        {
            messageRepository = repository;
        }

        public async Task<IEnumerable<Message>> GetChatMessages()
        {
            try
            {
                return await messageRepository.GetAll();
            } 
            catch (Exception ex)
            {
                throw;
            }
           
        }
    }
}

IMessageService

using Repositories.Models;

namespace Services.Services.interfaces
{
    public interface IMessageService
    {
        Task<IEnumerable<Message>> GetChatMessages();
        Task SendMessage(Message message);
        Task<Message> GetMessageById(int? id);
        void EditMessage(Message message);
        void DeleteMessage(int id);
    }
}

MessageRepository

using Microsoft.EntityFrameworkCore;
using Repositories.Contracts;
using Repositories.Data;
using Repositories.Models;

namespace Repositories.Repositories
{
    public class MessageRepository : IRepository<Message>
    {
        private readonly ApplicationDbContext _context;

        public MessageRepository(ApplicationDbContext context)
        {
            _context = context;
        }

        public async Task<IEnumerable<Message>> GetAll()
        {
            return await _context.Message.ToListAsync();
        }
    }
}

IRepository

using Repositories.Models;

namespace Repositories.Contracts
{
    public interface IRepository <T>
    {
        Task Create(T obj);
        Task<IEnumerable<T>> GetAll();
        void Update(T entity);
        void Delete(int id);
        Task<T> GetById(int? id);
    }
}

I don't know what I have to do to my services and repositories works

CodePudding user response:

The problem was solved removing the ApplicationDbContext appDbContext from contructor of repository, and remove the this._context = appDbContext too. but new error Object reference not set to an instance of an object.' in _context appears code after resolving Dependence injection, but with a new nullReference error in _context

CodePudding user response:

the final solution of the problem was add

builder.Services.AddScoped<IRepository<Message>, MessageRepository>();
builder.Services.AddScoped<IMessageService, MessageService>();
builder.Services.AddScoped<ApplicationDbContext, ApplicationDbContext>();

and complete contructor on repository

   public class MessageRepository : IRepository<Message>
    {

        private readonly ApplicationDbContext _context;

        public MessageRepository(ApplicationDbContext c)
        {
           this._context = c;
        }
  • Related