Вы должны , а не добавлять свои контексты отдельно в качестве области. Это основной источник вашей проблемы. Когда вы используете AddDbContext
, он регистрирует ваш класс DbContext
. Если вы продолжаете запрашивать интерфейс, он не знает, как удовлетворить этот интерфейс; он только знает, как удовлетворить класс. Вот почему вы получаете исключения, и именно поэтому вы чувствовали необходимость добавить отдельные регистрации интерфейса. Однако, когда вы делаете , что , вы запрашиваете другой экземпляр вашего контекстного класса, так как это совершенно другая регистрация.
Вам не нужен интерфейс для вашего контекста. Я вижу, что люди делают это все время, и это просто ошеломляет. Здесь абсолютно нулевая точка. Единственное, что должно быть общедоступно в вашем контексте, это ваши DbSet
свойства и встроенные методы, такие как Add
, SaveChangesAsync
и т. Д. Если вы хотите или должны работать с DbSet
в общем, есть Set<T>
для этого, так что ваш класс контекста может быть просто введен напрямую. Кроме того, не похоже, что у вас будет несколько реализаций этого контекста. Это представление вашей базы данных, и как таковое, это то, что есть: одна реализация на все времена.
Кроме того, вы не должны вводить что-либо в свой контекст, кроме DbContextOptions
. Если вам нужна услуга, у DbContext
есть внутренний поставщик услуг, и это то, что вы должны использовать, т.е. this.GetService<IAuthInfo>
.
UPDATE
Судя по ветке комментариев, я не думаю, что мне было понятно, что я предлагал. Вы должны иметь что-то вроде:
public interface IService
{
void DoSomething();
}
Затем вы создадите реализации this для каждого из ваших провайдеров, например CosmosDbService
, RavenDbService
, EFService
и т. Д. Затем в EFService
вы добавляете свой контекстный класс, не интерфейс :
public class EFService : IService
{
private readonly MyDbContext _context;
public EFService(MyDbContext context)
{
_context = context;
}
public void DoSomething()
{
// use _context
}
}
Таким образом, контекст только там ради EF. Там нет ничего постороннего, и там нет никакой бизнес-логики. Повсюду в вашем коде вы вводите IService
, а затем добавляете в соответствующую реализацию поставщика (EF, Cosmos, Raven и т. Д.) Через контейнер DI. Вся ваша бизнес-логика живет в классе обслуживания, как и должно быть, и вам не нужен интерфейс для вашего контекста.
Это также, вероятно, означает, что вам также не нужны посторонние услуги, такие как IAuthInfo
в вашем контексте, то есть вы можете избежать внутреннего поставщика услуг. Вместо этого вы вводите IAuthInfo
в свой класс обслуживания.
То, что вы делаете сейчас, является полной противоположностью. Вы принципиально запутываете свою бизнес-логику с EF, заставляя контекст реализовывать интерфейс, не имеющий ничего общего с его целью: служение простой единицей работы.