web-dev-qa-db-fra.com

Dépendance injecte DBContext dans le contrôleur MVC

Je me présente des inquiétudes concernant l'injection de mon cadre d'entité dBContext dans mon contrôleur MVC.

Vous trouverez ci-dessous un échantillon de mon code. La façon dont j'ai conçue, c'est que je puisse mieux tester mon code de contrôleur en injectant un dbcontext réel ou faux.

Ce que je pensais en train de faire, c'est utiliser Unity et l'interface des idbentités pour injecter le dBContext dans le contrôleur. Chaque fois qu'une nouvelle action est appelée à partir de ce contrôleur, l'unité appellera le constructeur du contrôleur et créera un nouvel objet DBContext qui implémente l'interface des idêties. De cette façon, j'ai un nouvel objet contextuel sur chaque nouvelle demande, que je pense est plutôt sûre.

Ma préoccupation est ce qui se passe ensuite. Dans l'action, je peux avoir plusieurs appels vers le même service de données ou un autre service de données utilisant le même objet dBContext. Par exemple, dans mon index (), je peux avoir des appels à mettre à jour à MeepectEvent (dbcontext), puis appellez SoftDeleeEvent (dBContext) à l'aide du même objet dBContext, ou même de transmettre le même contexte à un autre service de données, par exemple userservice.logOUtuser (dbcontext ).

Je ne sais pas si tout ce qui passe autour du même objet dbcontext est sûr.

est-il prudent de transmettre le dbcontext comme celui-ci ou existe-t-il un meilleur moyen d'extraire le dBContext du DataService dans le contrôleur à des fins de test de l'unité?

Manette:

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);
    }
}

Service de données:

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;
    }
}

Interface DBContext:

// This is an interface that my Entity Framework DbContext implements for Dependency Injection purposes
public interface IDbEntities
{
    DbSet<Event> Events { get; set; }
}
3
Mité

Vous devez injecter une nouvelle DbContext dans votre constructeur EventService, comme vous l'avez fait avec votre EventController.

DbContext Les objets sont des objets légers et courts. En passant le DbContext de votre eventController dans vos EventService méthodes crée un couplage inutile entre les classes sans fournir d'avantages supplémentaires et la gestion d'une durée de vie DbContext n'est pas la responsabilité d'un contrôleur De toute façon.

Si vous n'avez pas besoin de DbContext dans votre contrôleur (lorsque votre code de contrôleur semble suggérer), vous n'avez pas besoin de l'injecter dans le contrôleur du tout.

Les limites de la classe sont le niveau d'abstraction approprié pour un DbContext. En général, vous ne devriez pas partager un DbContext avec d'autres classes; Faites simplement une nouvelle pour chaque instance de classe.

1
Robert Harvey