#c# #asp.net-core #dependency-injection #dbcontext
#c# #asp.net-core #внедрение зависимости #dbcontext
Вопрос:
Я пытаюсь настроить DI для нового ASP.NET Основной сайт и у меня есть этот код:
public void ConfigureServices(IServiceCollection services)
{
services
.AddMvc()
.SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
// Get the configuration from the app settings.
var config = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("appsettings.json")
.Build();
// Get app settings to configure things accordingly.
var appSettings = Configuration.GetSection("AppSettings");
var settings = new AppSettings();
appSettings.Bind(settings);
services
.AddOptions()
.Configure<AppSettings>(appSettings)
.AddSingleton<IConfigurationRoot>(config)
.AddDbContext<MyDbContext>(builder =>
{
builder.UseSqlServer(config.GetConnectionString("myConn"));
}, ServiceLifetime.Transient, ServiceLifetime.Transient);
services.AddSingleton<ILoadTestCleanUpServiceRepository, LoadTestCleanUpServiceRepository>();
...
Теперь LoadTestCleanUpServiceRepository
зависит от MyDbContext
:
public class LoadTestCleanUpServiceRepository : ILoadTestCleanUpServiceRepository
{
private readonly MyDbContext _dbContext;
public LoadTestCleanUpServiceRepository(MyDbContext dbContext)
{
_dbContext = dbContext;
}
...
..и контекст БД такой:
public class MyDbContext : DbContext
{
public MyDbContext(DbContextOptions<MyDbContext> ctxOptions) : base(ctxOptions)
{
}
}
Когда я запускаю приложение, я получаю эту ошибку:
Исключение InvalidOperationException: не удается разрешить службу для типа ‘MyCode.Инфраструктура.Обычный.MyDbContext’ при попытке активировать ‘MyCode.Инфраструктура.LoadTestCleanUpService.LoadTestCleanUpServiceRepository’.
Я попытался изменить ServiceLifetime
параметры и добавить этот дополнительный код:
services.AddTransient<MyDbContext>(sp => new MyDbContext(config));
… но, похоже, ничего не помогает, и я не могу понять, почему это не работает. Он пытается создать репозиторий, но почему он не может также создать контекст DB? Это даже не доходит до того момента, когда я вызываю UseSqlServer()
!
Есть идеи?
ОБНОВЛЕНИЕ 1:
Хм… Теперь я вижу это. Скорее всего, это связано:
ОБНОВЛЕНИЕ 2:
Теперь у меня есть :
- Заменил EF 6 на Microsoft.EntityFrameworkCore.SQLServer
- Обновлен до целевой платформы netcoreapp2.2 для решения некоторых конфликтующих версий сборки.
- Сделал репозиторий ограниченным.
Но я все еще получаю ту же ошибку.
Комментарии:
1. Почему класс MyDbContext имеет AcDbContext для конструктора? Этот код компилируется?
2. @Dimitar Извините. Теперь я это исправил. Я «меняю» некоторые части кодовых имен, чтобы избежать утечки информации о моем проекте. Это не какой-то сверхсекретный материал, но я стараюсь сделать код как можно более «общим».
3. У меня была похожая проблема, и да, несоответствие версии EF является единственным объяснением этого
4. Вы не можете использовать контекст базы данных с ограниченной областью действия в одноэлементной службе. Попытка сделать контекст базы данных временным также не исправит это. Подумайте о том, чтобы вместо этого ограничить область действия вашего репозитория.
5. Имейте в виду, что ваш
MyDbContext
находится в плену как зависимая внутриLoadTestCleanUpServiceRepository
.
Ответ №1:
Я вижу, что вы зарегистрировались LoadTestCleanUpServiceRepository
как Singleton
, в то время как MyDbContext
как Transient
, а затем пытаетесь разрешить MyDbContext
из LoadTestCleanUpServiceRepository
. В этом проблема. Согласно ASP.NET Сроки службы ядра документация:
Опасно разрешать службу с ограниченной областью действия / временную службу из синглтона. Это может привести к некорректному состоянию службы при обработке последующих запросов.
Решение таково: зарегистрируйтесь LoadTestCleanUpServiceRepository
и MyDbContext
следующим образом:
services.AddDbContext<MyDbContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("YourConnectionStringName")));
services.AddScoped<ILoadTestCleanUpServiceRepository, LoadTestCleanUpServiceRepository>();
Теперь проблема должна исчезнуть.
Комментарии:
1. Спасибо. После многих изменений это сработало. Одна вещь, которая была действительно неправильной, заключалась в том, что я определил два разных контекста БД (случайно после попытки переместить один контекст БД), и это все испортило.