Внедрение зависимости не разрешает унаследованный сервис (DbContext) - PullRequest
1 голос
/ 01 апреля 2020

Я пытаюсь зарегистрировать один из двух имеющихся у меня dbcontexts, основываясь на передаваемом мной ключе, который означает, что я хочу заполнить базу данных или просто запустить службу. Итак, я делаю это на ConfigureServices:

//Add DB Service for application
bool seedDb = Configuration.GetValue<bool>("seeddb");

if(seedDb)
    services.AddDbContext<ApplicationDbSeedDataContext>(options => options.UseMySql(Configuration.GetConnectionString("DefaultConnection")));
else
    services.AddDbContext<ApplicationDbContext>(options => options.UseMySql(Configuration.GetConnectionString("DefaultConnection")));

Иерархия классов действительно проста:

public class ApplicationDbContext : DbContext
{ 
    public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options, IHttpContextAccessor httpContextAccessor) : base(options)
    {
        _httpContextAccessor = httpContextAccessor;
    }
}

public class ApplicationDbSeedDataContext : ApplicationDbContext
{
    public ApplicationDbSeedDataContext(DbContextOptions<ApplicationDbContext> options) : base(options, new HttpContextAccessor())
    {
    }
} 

Тогда я просто ожидаю, что в любом методе, запрашивающем ApplicationDbContext, который вводит система DI тот, который я создал, но он не работает, когда я внедряю ApplicationDbSeedDataContext вместо ApplicationDbContext.

Но я получаю ошибку:

System.InvalidOperationException: Ошибка при проверке дескриптора службы 'ServiceType: WebAPI.Services.IUserService. Время жизни: область применения. Тип реализации: WebAPI.Services.UserService. Не удается разрешить службу для типа «WebAPI.Contexts.ApplicationDbContext» при попытке активировать «WebAPI.Services.UserService».

Конструктор Userservice:

public class UserService : IUserService
{
    public UserService(IConfiguration configuration, ApplicationDbContext dbContext)
    {
        _configuration = configuration;
        _dbContext = dbContext;
    }

    ...
}

Разве это не должно быть решено правильно?

1 Ответ

0 голосов
/ 01 апреля 2020

С этим

services.AddDbContext<ApplicationDbSeedDataContext>(...);

Контейнер не будет знать о базе ApplicationDbContext

Они должны быть зарегистрированы как того же типа.

Используйте регистрацию перегрузки AddDbContext, чтобы явно указать базовый тип

//Add DB Service for application
bool seedDb = Configuration.GetValue<bool>("seeddb");

if(seedDb)
    services.AddDbContext<ApplicationDbContext, ApplicationDbSeedDataContext>(options => ...);
else
    services.AddDbContext<ApplicationDbContext>(options => ...);

При этом старайтесь избегать инъекций и использования IConfiguration вне Startup Это действительно не подразумевалось для этого и может рассматриваться как запах кода в большинстве случаев (нарушение SRP), рассмотреть возможность использования шаблона параметров

...