Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unable to resolve service for type in ApplicationDbContext

When I'm trying to add migrations with dnx ef migrations add Mig, I have the following exception in console:

Unable to resolve service for type 'Microsoft.AspNet.Http.IHttpContextAcccessor' while attempting to activate 'NewLibrary.Models.ApplicationDbContext'.

My ApplicationDbContext:

public class ApplicationDbContext : DbContext
{
    private readonly IHttpContextAccessor _accessor;

    public ApplicationDbContext(IHttpContextAccessor accessor)
    {
        _accessor = accessor;
    }
}

What's the problem?

How should I correctly add dependencies to ApplicationDbContext constructor?

like image 593
Yurii N. Avatar asked Apr 25 '16 15:04

Yurii N.


2 Answers

DI would not have been setup via command line, which is why you are getting the above exception.

In the comments you explain that you want access to the HttpContext via IHttpContextAccessor which is something that is usually available at run time.

Migrations are not applied at run time, where DI would have been configured and available.

You may need to read up on Configuring a DbContext. This documentation is for EF7 onwards

like image 126
Nkosi Avatar answered Oct 11 '22 16:10

Nkosi


I found this forum that led me to the following solution: https://github.com/aspnet/EntityFrameworkCore/issues/4232

Create a new service class and interface:

    using Microsoft.AspNetCore.Http;
    using MyProject.Interfaces;
    using System.Collections.Generic;
    using System.Linq;

    namespace MyProject.Web.Services
    {
        public interface IUserResolverService
        {
            string GetCurrentUser();
        }

        public class UserResolverService : IUserResolverService
        {
            private readonly IHttpContextAccessor _context;
            public UserResolverService(IEnumerable<IHttpContextAccessor> context)
            {
                _context = context.FirstOrDefault();
            }

            public string GetCurrentUser()
            {
                return _context?.HttpContext?.User?.Identity?.Name ?? "unknown_user";
            }
        }
    }

And register it with your DI container (Startup.cs for example)

    services.AddTransient<IUserResolverService, UserResolverService>();

Then in your DbContext, use the userResolverService to get the username instead of IHTTPContextAccessor

    private readonly IUserResolverService userResolverService;
    public ApplicationDbContext(IUserResolverService userResolverService) : base()
    {
        this.userResolverService = userResolverService;

        var username = userResolverService.GetCurrentUser();
...
like image 24
patrickbadley Avatar answered Oct 11 '22 14:10

patrickbadley