Ho capito guardando questo video con Rowan Miller https://channel9.msdn.com/Series/Whats-New-with-ASPNET-5/06 (al minuto 22) il modo di configurare Entity Framework Core (precedentemente noto come EF7 ) in un'app di ASP.NET Core 1.0 (precedentemente nota come ASP.NET 5) in Startup.cs
è la seguente:
public void ConfigureServices(IServiceCollection services)
{
//Entity Framework 7 scoped per request??
services.AddEntityFramework()
.AddSqlServer()
.AddDbContext<MyDbContext>(options =>
{
options
.UseSqlServer(Configuration["Data:DefaultConnection:ConnectionString"]);
});
//MVC 6
services.AddMvc();
}
e che questo DbContext sarà sottoposto a una richiesta http in modo tale che ogni volta che si utilizza il codice in tutta la pipeline http (incluso middleware o MVC) si utilizzi un DbContext, sappiamo per certo che l'istanza iniettata dal contenitore DI sarà la stessa.
Ma il problema è che non sembra funzionare in questo modo. Durante la vita di MVC è vero che l'istanza di DbContext iniettata è la stessa, ma come descritto qui: Entity Framework Core 1.0 unità di lavoro con il middleware Asp.Net Core o il filtro Mvc Sto provando a collegare alla pipeline il seguente middleware per ottenere una sorta di Commit / Rollback centralizzato dopo che un controllore ha finalizzato l'esecuzione:
public class UnitOfWorkMiddleware
{
private readonly RequestDelegate _next;
private readonly MyDbContext _dbContext;
private readonly ILogger _logger;
public UnitOfWorkMiddleware(RequestDelegate next, MyDbContext dbContext, ILoggerFactory loggerFactory)
{
_next = next;
_dbContext = dbContext;
_logger = loggerFactory.CreateLogger<UnitOfWorkMiddleware>();
}
public async Task Invoke(HttpContext httpContext)
{
await _next.Invoke(httpContext);
_logger.LogInformation("Saving changes for unit of work if everything went good");
await _dbContext.SaveChangesAsync();
}
}
e questo middleware è immediatamente precedente rispetto a MVC6 nella pipeline
//inside Configure(IApplicationBuilder app) in Startup.cs
app.UseMiddleware<UnitOfWorkMiddleware>();
app.UseMvcWithDefaultRoute();
L'istanza di DbContext nel mio middleware non è uguale all'istanza che viene iniettata durante la durata di MVC .
È previsto? Non dovrebbe essere un ambito DbContext ad una richiesta http? È possibile ottenere ciò che stavo cercando di ottenere?
Il piano B sarebbe utilizzare un filtro globale MVC 6 (se riesco a trovare qualche documentazione su come farlo). Presumo che facendo parte del framework MVC 6, l'istanza di DbContext iniettata sarà la stessa ..
Dopo ulteriori test, posso confermare che DbContext è limitato alla richiesta http solo durante la durata dell'esecuzione MVC (forse MVC è responsabile della disposizione di DbContext), quindi qualsiasi middleware prima o dopo nella pipeline non avrà il stessa istanza di DbContext iniettata.
Ho deciso quindi di aggiungere un filtro globale a MVC 6 (perché i filtri fanno parte del framework MVC) in modo che possa accedere alla stessa istanza di DbContext prima e dopo l'esecuzione dell'azione.
Se qualcuno è interessato a come creare questo controllo globale del filtro: Entity Framework Core 1.0 unità di lavoro con middleware Asp.Net Core o filtro Mvc