Sto cercando di sviluppare una libreria di classi in cui voglio implementare DbContext
personalizzato. Nel metodo SaveChanges
di DbContext
, ho bisogno di ottenere le informazioni dell'utente corrente (dipartimento, nome utente ecc.) Per scopi di controllo. Alcune parti del codice DbContext
sono qui sotto:
public override int SaveChanges()
{
// find all changed entities which is ICreateAuditedEntity
var addedAuditedEntities = ChangeTracker.Entries<ICreateAuditedEntity>()
.Where(p => p.State == EntityState.Added)
.Select(p => p.Entity);
var now = DateTime.Now;
foreach (var added in addedAuditedEntities)
{
added.CreatedAt = now;
added.CreatedBy = ?;
added.CreatedByDepartment = ?
}
return base.SaveChanges();
}
Mi vengono in mente due opzioni:
HttpContext.Items
per mantenere le informazioni dell'utente, iniettare IHttpContextAccessor e ottenere informazioni da HttpContext.Items
(in questo caso DbContext
dipende da HttpContext
, è corretto?) HttpContext.Items
e ottenendo informazioni dall'oggetto (ho letto alcuni post che ThreadStatic non è sicuro) Domanda : qual è la soluzione migliore per il mio caso? C'è un altro modo che suggerisci?
Ho implementato un approccio simile a questo che è coperto in questo post del blog e fondamentalmente comporta la creazione di un servizio che utilizzerà l'iniezione di dipendenza per iniettare HttpContext
(e le informazioni utente sottostanti) in un particolare contesto, o comunque si preferisce usarlo.
Un'implementazione di base potrebbe essere simile a questa:
public class UserResolverService
{
private readonly IHttpContextAccessor _context;
public UserResolverService(IHttpContextAccessor context)
{
_context = context;
}
public string GetUser()
{
return _context.HttpContext.User?.Identity?.Name;
}
}
Dovresti semplicemente inserirli nella pipeline all'interno del metodo ConfigureServices
nel tuo file Startup.cs
:
services.AddTransient<UserResolverService>();
E infine, basta accedervi all'interno del costruttore del DbContext
specificato:
public partial class ExampleContext : IExampleContext
{
private YourContext _context;
private string _user;
public ExampleContext(YourContext context, UserResolverService userService)
{
_context = context;
_user = userService.GetUser();
}
}
Quindi dovresti essere in grado di usare _user
per fare riferimento all'utente corrente nel tuo contesto. Questo può essere facilmente esteso per archiviare / accedere a qualsiasi contenuto disponibile all'interno della richiesta corrente.