Dependency Inject DbContext in MVC Controller

3

Ho qualche dubbio sull'iniettare il mio Entity Framework DbContext nel mio controller MVC.

Di seguito è riportato un esempio del mio codice. Il modo in cui ho progettato questo è che posso testare meglio il mio codice del controller iniettando un DbContext reale o fittizio.

Quello che sto pianificando di fare è usare Unity e l'interfaccia IDbEntities per iniettare DbContext nel controller. Ogni volta che viene chiamata una nuova azione da questo controller, Unity chiamerà il costruttore del controller e creerà un nuovo oggetto DbContext che implementa l'interfaccia IDbEntities. In questo modo ho un nuovo oggetto di contesto su ogni nuova richiesta, che credo sia abbastanza sicuro.

La mia preoccupazione è ciò che accadrà dopo. Nell'azione, posso avere più chiamate allo stesso o a diversi servizi dati utilizzando lo stesso oggetto DbContext. Ad esempio, nella mia azione Index () posso avere chiamate UpdateEvent (dbContext) e quindi chiama SoftDeleteEvent (dbContext) utilizzando lo stesso oggetto DbContext o passa lo stesso contesto a un altro servizio dati, ad esempio UserService.LogoutUser (dbContext).

Non sono sicuro che tutto questo passaggio dello stesso oggetto DbContext sia sicuro.

È sicuro passare il DbContext in questo modo o esiste un modo migliore per estrarre DbContext dal DataService nel Controller per scopi di test unitari?

Controller:

public class EventsController : Controller
{    
    private IDbEntities _dbContext;

    public EventsController(IDbEntities entities)
    {
        _dbContext = entities;
    }

    public ActionResult Index()
    {
        // Hypothetical operations. In reality update and delete of the same record rarely happen in the same code branch
        var events = _eventService.AllEvents(_dbContext);
        _eventService.UpdateEvent(id, "NewName", _dbContext);
        _eventService.SoftDeleteEvent(id, _dbContext);

        return View(events);
    }
}

Servizio dati:

public class EventService : IEventService
{
    public IEnumerable<Event> AllEvents(IDbEntities entities)
    {
        return entities.Events.ToList();
    }

    public void UpdateEvent(Guid id, string name, IDbEntities entities)
    {
        var item = entities.Events.Find(id);
        if (item != null)
        {
            item.Name = name;
            entities.SaveChanges();
        }
    }

    public bool SoftDeleteEvent(Guid id, IDbEntities entities)
    {
        var item = entities.Events.Find(id);
        if (item != null)
        {
            item.Purged = true;
            entities.SaveChanges();
        }

        return true;
    }
}

Interfaccia DbContext:

// This is an interface that my Entity Framework DbContext implements for Dependency Injection purposes
public interface IDbEntities
{
    DbSet<Event> Events { get; set; }
}
    
posta Mité 25.10.2017 - 18:14
fonte

1 risposta

1

Devi inserire una nuova DbContext nel tuo costruttore di EventService , proprio come hai fatto con EventController .

DbContext oggetti sono oggetti leggeri e di breve durata. Passare il DbContext dal tuo EventController nei tuoi metodi EventService crea un accoppiamento non necessario tra le classi senza fornire alcun vantaggio aggiuntivo, e gestire la durata di un DbContext non è comunque responsabilità di un controller.

Se non hai bisogno del DbContext nel tuo controller (come sembra suggerire il codice del controller), non è necessario inserirlo nel controller.

I limiti della classe sono il livello appropriato di astrazione per un DbContext . In generale, non devi condividere DbContext con altre classi; creane uno nuovo per ogni istanza di classe.

    
risposta data 25.10.2017 - 18:58
fonte

Leggi altre domande sui tag