0

I am using Asp .Net 5 to create a WebApi and I am trying to put all database operations in a separate class, the problem is I can't Use ApplicationDbContext by initiating a new object because it takes an argument in the constructor.

my context :

 public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options) : base(options)
        {
        }

controller :

[Route("api/[controller]")]
    [ApiController]
    public class AttributesController : ControllerBase
    {
        [HttpPost]
        [Route("GetAllAttributes")]
        public async Task<AllAttributes> GetAllAttributes()
        {
            return await new Services.AttributeService().GetAll();
        }
    }

service :

public class AttributeService
    {
        private readonly ApplicationDbContext _db ;
        public async Task<AllAttributes> GetAll()
        {
            try
            {
                var dbAttributes = await _db.Attributes.Where(attr=> (bool)attr.IsActive && !(bool)attr.IsDeleted && !(bool)attr.IsTrashed).ToListAsync();
                if (dbAttributes.Count>0)
                {
                    return new AllAttributes
                    {
                        Attributes = dbAttributes,
                        Message = new ResponseMessage
                        {
                            Message = "Success",
                            Code = 200
                        }
                    };
                }
                else
                {
                    return new AllAttributes
                    {
                        Message = new ResponseMessage
                        {
                            Message = "Empty",
                            Code = 410
                        }
                    };
                }
                
            }
            catch (Exception ex)
            {
                return new AllAttributes
                {
                    Message = new ResponseMessage
                    {
                        Message = ex.Message,
                        Code = 500
                    }
                };
            }
        }}

so when I call it like this I got NullReference Exception.

esamaldin elzain
  • 320
  • 1
  • 4
  • 16
  • Register either AttributeService and DbContext to DI container and use injection to reach them. – Berkay Yaylacı Mar 07 '21 at 12:17
  • Does this answer your question? [Injecting DbContext into service layer](https://stackoverflow.com/questions/41058142/injecting-dbcontext-into-service-layer) – Christian Gollhardt Mar 07 '21 at 13:00
  • @ChristianGollhardt I did all this, my problem was in the Controller constructor to pass the service `public AttributesController(AttributeService _attributeService) { attributeService = _attributeService; }` which is not mentioned there – esamaldin elzain Mar 07 '21 at 13:07

1 Answers1

1

You will need to add AttributeService to the DI container. You can do this inside ConfigureServices method of Startup.cs:

services.AddScoped<AttributeService>();

Then you can inject the context in the constructor of AttributeService:

public class AttributeService
{
    private readonly ApplicationDbContext _db ;

    public AttributeService(ApplicationDbContext db) 
    {
        _db = db;
    }
    ...
 }
haldo
  • 14,512
  • 5
  • 46
  • 52
  • Yes it's working now using DI and inject the service to the DI container `[Route("api/[controller]")] [ApiController] public class AttributesController : ControllerBase { private readonly AttributeService attributeService; public AttributesController(AttributeService _attributeService) { attributeService = _attributeService; } [HttpPost] [Route("GetAllAttributes")] public async Task GetAllAttributes() { return await attributeService.GetAll(); } }` – esamaldin elzain Mar 07 '21 at 12:32