Я делаю n-уровневое приложение MVC, используя .NET Core 2.1 и Entity Framework. Есть также размещенная очередь MQTT, в которой мое приложение слушает как клиент. Я также использую инъекцию зависимости. Это работает отлично, пока сообщение не будет помещено в очередь, и я хочу сохранить это сообщение в БД. Как только это происходит, я получаю следующее сообщение об ошибке ObjectDisposedException
:
Невозможно получить доступ к удаленному объекту. Распространенной причиной этой ошибки является удаление контекста, который был разрешен путем внедрения зависимости, а затем попытка использовать тот же экземпляр контекста в другом месте вашего приложения. Это может произойти, если вы вызываете Dispose () для контекста или заключаете контекст в оператор using. Если вы используете внедрение зависимости, вы должны позволить контейнеру введения зависимости позаботиться об удалении экземпляров контекста. Имя объекта: 'xxxDbContext'.
Я могу нажать продолжить, после чего приложение просто продолжает работать. Он создает исключение только для первого сообщения, полученного из очереди. Любое другое действие с контроллерами / менеджерами / репозиториями работает просто отлично. Мой код выглядит следующим образом:
Startup.cs
public void ConfigureServices(IServiceCollection services)
{
services.AddDefaultIdentity<User>()
.AddEntityFrameworkStores<xxxDbContext>();
services.AddDbContext<xxxDbContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")
));
// Some identity configuration omitted here
services.AddScoped<IIdeationRepository, IdeationRepository>();
services.AddScoped<IIdeationManager, IdeationManager>();
// Some other DI configuration omitted as well.
}
public Configure(IApplicationBuilder app, IHostingEnvironment env,
IApplicationLifetime applicationLifetime, IServiceProvider serviceProvider)
{
// Start MQTT
var broker = new MqttBroker(serviceProvider.GetService<IIdeationManager>(),
serviceProvider.GetService<IConfiguration>());
// On application exit terminate MQTT to make sure the connection is ended properly
applicationLifetime.ApplicationStopping.Register(() => broker.Terminate());
// Some default http pipeline code omitted
}
MqttBroker.cs
public MqttBroker(
[FromServices] IIdeationManager ideationManage,
[FromServices] IConfiguration configuration)
{
_ideationManager = ideationManager;
_configuration = configuration;
Initialize();
}
// Some code where I just parse the message and on receive send it to the
// ideation manager, this just works so I omitted it.
}
Менеджер просто отправляет его прямо в хранилище, где появляется сообщение об ошибке.
Repository.cs
private xxxDbContext ctx;
public IdeationRepository(xxxDbContext xxxDbContext)
{
this.ctx = xxxDbContext;
}
// This method crashes with the error
public IdeationReply ReadIdeationReply(int id)
{
return ctx
.IdeationReplies
.Include(r => r.Votes)
.FirstOrDefault(r => r.IdeationReplyId == id);
}
DbContext.cs
public class xxxDbContext : IdentityDbContext<User>
{
public DbSet<Ideation> Ideations { get; set; }
// Some more dbsets omitted
public CityOfIdeasDbContext(DbContextOptions<CityOfIdeasDbContext> options)
: base (options)
{
CityOfIdeasDbInitializer.Initialize(this, dropCreateDatabase: false);
}
// In configuring I just create a logger, nothing special
// In OnModelCreating I just setup some value converters for other tables
// than the ones I need here
internal int CommitChanges()
{
if (delaySave)
{
int infectedRecords = base.SaveChanges();
return infectedRecords;
}
throw new InvalidOperationException(
"No UnitOfWork present, use SaveChanges instead");
}
}
Я прочитал это , но ни одна из этих ситуаций, кажется, не относится ко мне. И когда я печатаю трассировку стека в Dispose()
, это происходит методом Main()
, поэтому мне это не очень помогает.
Кто-нибудь знает, как решить или где я могу найти, чтобы решить эту проблему?
Заранее спасибо!