Combinazione del modello di repository, unità di lavoro e framework di entità

0

Mi chiedo come combinare correttamente EF, Pattern di deposito e Unità di lavoro.

La soluzione che ho è del tutto corretta?

L'esempio qui sotto riguarda l'app Todo

ProjectController

 public class ProjectController : Controller
    {
        private readonly IProjectService _pService; //it sholud be 

        public ProjectController(ProjectService pService)
        {
            _pService = pService;
        }

        [HttpGet]
        public async Task<IActionResult> GetAsync()
        {
            var project = await _pService.GetAsync(1);

            return Json(project);
        }
    }

ProjectService che ha una proprietà che è un UnitOfWork specifico.

public interface IProjectService 
    {
        Task<Project> GetAsync(int id); 
    }
    public class ProjectService : IProjectService
    {
        private readonly ITodoUnitOfWork _unitOfWork;
        public ProjectService(ITodoUnitOfWork unitOfWork)
        {
            _unitOfWork = unitOfWork;
        }

        public async Task<Project> GetAsync(int id)
        {
            var project = await _unitOfWork.Projects.GetAsync(id);

            return project;
        }
    }

UnitOfWork

public interface ITodoUnitOfWork
{
     IProjectRepository Projects { get; }
     ITaskRepository Tasks { get; }
     Task Complete();
}    

public class UnitOfWork : ITodoUnitOfWork
{
    private readonly DbContext _context;
    public IProjectRepository Projects { get; protected set; }
    public ITaskRepository Tasks { get; private set; }
    public UnitOfWork(TodoContext todoContext, IProjectRepository projectRepository, 
            ITaskRepository taskRepository)
    {
        _context = todoContext;
        Projects = projectRepository;
        Tasks = taskRepository;
    }

    public async Task Complete()
    {
        await _context.SaveChangesAsync();
    }
}

ProjectRepository

public interface IProjectRepository 
{
    //Minimal inteface
    Task<Project> GetAsync(int id);
}

public class ProjectRepository : IProjectRepository
{
    private readonly TodoContext _context;
    public ProjectRepository(TodoContext context)
    {
        _context = context;
    }
    public async Task<Project> GetAsync(int id)
    {

        var project = _context.Projects
                            .Include(x => x.Tasks)
                            .FirstOrDefault(x => x.Id == id)
                        ;

        return await Task.FromResult(project);
    }
}

TodoContext

public class TodoContext : DbContext
{
    public DbSet<Tassk> Tasks { get; set; }
    public DbSet<Project> Projects { get; set; }
    public TodoContext(DbContextOptions options) : base(options)
    {

    }
}

Non preoccuparti delle interfacce minimaliste e che sono posizionate nei file di implementazione. È solo un esempio

Non ho un'interfaccia generica per il repository. È utile avere un'interfaccia generica che contenga solo i tipici metodi CRUD?

Quali DbSet devono essere inseriti nella classe che interpone DbContext?

Devo creare una classe DbContext e inserire tutti i DbSet, oppure dovrei creare un paio di classi di contesto?

Eg. in basso:

SingleContext

public class SingleContext : DbContext
{
    public DbSet<Tassk> Tasks { get; set; }
    public DbSet<Project> Projects { get; set; }
    public DbSet<User> Users { get; set; }
    public DbSet<Role> Roles { get; set; }
    public DbSet<Setting> Settings { get; set; }

    //etc....
}

Contesti multipli

UserContext

public class UserContext : DbContext
{
    public DbSet<User> Users { get; set; }
    public DbSet<Role> Roles { get; set; }

    //etc....
} 

TodoContext

public class TodoContext : DbContext
{
    public DbSet<Tassk> Tasks { get; set; }
    public DbSet<Project> Projects { get; set; }

    //etc....
}    

Contesto applicazione

public class ApplicationContext : DbContext
{
    public DbSet<Setting> Settings { get; set; }
    //etc....
} 
    
posta bielu000 30.08.2017 - 09:15
fonte

0 risposte