web-dev-qa-db-fra.com

Comment concevoir un modèle de référentiel avec injection de dépendance dans ASP.NET Core MVC?

Étant assez nouveau dans ASP.NET Core 1.0 MVC, j'ai décidé d'utiliser un modèle de référentiel pour une application MVC Core; J'utilise une base de données SQL pour la couche de données SampleDbContext et je souhaite disposer d'une classe de référentiel pour certaines de mes entités métier. Jusqu'ici j'ai fait ce qui suit dans thestartup.cs, CustomerController.cs et CustomerRepository.cs fichiers, où un exemple d'entité est "Client".

Dans la méthode ConfigureServices de la classe de démarrage:

public void ConfigureServices(IServiceCollection services)
{
    services.AddDbContext<SampleDbContext>(options =>
       options.UseSqlServer(Configuration.GetConnectionString("SampleDB")));
}

Dans un contrôleur:

public class CustomerController : Controller
{

    private SampleDBContext _context;
    private CustomerRepository = new CustomerRepository (new SampleDBContext());

    public CustomerController(SampleDBContext context)
    {
        _context = context;
    }
}

Dans un référentiel:

public class CustomerRepository
{
    private SampleDBContext _context;

    public CustomerRepository(SampleDBContext context)
    {
        _context = context;
    }
}

Avec ce design, je branche le SampleDbContext en tant que service dans le startup.cs une fois, puis pour chaque contrôleur (qui reçoit une injection de dépendance), j'instancie un référentiel correspondant en transmettant une nouvelle instance de SampleDbContext. Cette instanciation répétitive du contexte de base de données est-elle une bonne conception pour un environnement multi-utilisateur? Je suppose que je pourrais ajouter chaque référentiel en tant que service à la startup.cs mais ça n'a pas l'air bien. Dites-moi s'il vous plaît une bonne mise en œuvre de la conception pour mon cas ou mettez-moi dans la bonne voie si je suis perdu.

19
Giancarlo Sierra

Vous pouvez voir exemple simple comment utiliser le modèle de référentiel:

Vous créez une interface de référentiel:

using System.Collections.Generic;

namespace TodoApi.Models
{
    public interface ITodoRepository
    {
        void Add(TodoItem item);
        IEnumerable<TodoItem> GetAll();
        TodoItem Find(long key);
        void Remove(long key);
        void Update(TodoItem item);
    }
}

Puis implémentez-le:

using System;
using System.Collections.Generic;
using System.Linq;

namespace TodoApi.Models
{
    public class TodoRepository : ITodoRepository
    {
        private readonly TodoContext _context;

        public TodoRepository(TodoContext context)
        {
            _context = context;
            Add(new TodoItem { Name = "Item1" });
        }

        public IEnumerable<TodoItem> GetAll()
        {
            return _context.TodoItems.ToList();
        }

        public void Add(TodoItem item)
        {
            _context.TodoItems.Add(item);
            _context.SaveChanges();
        }

        public TodoItem Find(long key)
        {
            return _context.TodoItems.FirstOrDefault(t => t.Key == key);
        }

        public void Remove(long key)
        {
            var entity = _context.TodoItems.First(t => t.Key == key);
            _context.TodoItems.Remove(entity);
            _context.SaveChanges();
        }

        public void Update(TodoItem item)
        {
            _context.TodoItems.Update(item);
            _context.SaveChanges();
        }
    }
}

Puis enregistrez-vous dans ConfigureServices:

services.AddSingleton<ITodoRepository, TodoRepository>();

Puis injectez-le au contrôleur:

namespace TodoApi.Controllers
{
    [Route("api/[controller]")]
    public class TodoController : Controller
    {
        public TodoController(ITodoRepository todoItems)
        {
            TodoItems = todoItems;
        }
        public ITodoRepository TodoItems { get; set; }
    }
}
28
Alexan

Certains soutiennent que DbContext lui-même est un modèle de référentiel. Si vous souhaitez suivre cette voie, vous pouvez télécharger l'exemple de code à partir de ASP.NET Core et Angular 2 .

Par exemple -

public class CustomerController : Controller
{
    private SampleDBContext _context;

    public CustomerController(SampleDBContext context)
    {
        _context = context;
    }

    public async Task<IActionResult> Index(int id)
    {
        var user = _context.Users.Where(i => i.Id == id).FirstOrDefault();
        ...
    }
}

Startup.cs

public void ConfigureServices(IServiceCollection services)
{
    services.AddDbContext<SampleDBContext>(options =>
        options.UseSqlServer(Configuration["Data:DefaultConnection:ConnectionString"])
        );
}
2
Win

Je ne suis pas sûr que ce soit la meilleure méthode, mais j'ai toujours créé le référentiel comme une interface implémentée par les contrôleurs.

IRepository.cs:

public interface IRepository
{
     SomeList GetSomeList(string userId);
     Some GetSomeDetail(int someId);
}

DbInterface.cs:

public class DbInterface : IRepository
{
    public SomeList GetSomeList(string userId)
    {

    }

    public Some GetSomeDetail(int someId)
    {

    }
}

SomeList étant un type de données que j'ai défini avec toutes les propriétés à afficher sur une page sous forme de liste. C'est à dire. une liste de tâches dans une application de tâches. Certains étant un type de données défini qui renvoie les détails de a tâche (l’entrée serait alors taskId ou autre).

Heureux d'être corrigé s'il s'agit d'une mauvaise méthode.

1
Kris.J