Область ответственности между Контроллером и Репозиторием в ASP.Net MVC2 - PullRequest
2 голосов
/ 16 июля 2010

Я пытаюсь понять, как структурировать веб-приложение ASP.Net MVC2 с использованием репозиториев.

Множество примеров, учебников и книг, которые я прочитал, структурируют приложение так:

public interface IProductsRepository
{
    IQueryable<Product> Products { get; }
}

public class SqlProductsRepository : IProductsRepository
{
    public Table<Product> productsTable;

    public IQueryable<Product> Products
    {
        get { return productsTable }
    }
}

public class ProductsController : Controller
{
    IProductsRepository productsRepository;
    public ProductsController(IProductsRepository productsRepository)
    {
       // set the Repository
    }

    public ActionResult GetLatestPublishedProducts(int pageSize, int page, ref int totalItemCount)
    {
        // Do LINQ query 
        return View(from p in productsRepository
                    where p.PublishedOn != null 
                    orderby p.ProductId descending 
                    select to(p))
                    .Skip((page  - 1) * pageSize)
                    .Take(pageSize)
                    .ToList());
    }
}

Одна вещь, которую я не понимаю, это то, почему запрос Linq живет в контроллере.

Я хотел бы знать, почему делать что-то подобное неправильно:

public class SqlProductsRepository : IProductsRepository
{
    // set data model stuff here

    public List<Product> GetLatestPublishedProducts(int pageSize, int page, ref int totalItemCount) {
        // DO LINQ Query in here
    }
}

public class ProductsController : Controller
{
    // set repository stuff here

    public ActionResult GetLatestPublishedProducts(int pageSize, int page, ref int totalItemCount)
    {       
        return View(productsRepository.GetLatestPublishedProducts(pageSize, page, totalItemCount));
    }
}

Ответы [ 3 ]

7 голосов
/ 16 июля 2010

Ваш второй пример - это то, что вы должны делать.Репозитории должны обрабатывать все данные доступа.

Контроллер должен только получать уже отфильтрованные / отсортированные данные и передавать их в представление.Контроллер не должен отвечать за любые данные или бизнес-логику.Он должен отвечать только за получение данных и их передачу.

При написании кода в контроллере я задаю себе этот вопрос;

Придется ли мне снова писать этот код, еслиЯ должен был написать это приложение в WinForms?

Таким образом, ваш IProductsRepository будет иметь метод GetLatestPublishedProducts, который вы затем реализуете в своем SqlProductsRepository.

.обязанности:

  • Репозиторий - Получает данные из базы данных
  • Контроллер - Передает данные в представление для рендеринга

Затем вы можете сделать еще один шаг и отделить любую бизнес-логику, чтобы сам контроллер не использовал репозитории.Таким образом, у вас будет третий Сервисный уровень, который находится между Контроллером и Репозиторием.

4 голосов
/ 16 июля 2010

Проверьте намерения разных классов.

  • Репозиторий: предоставить доступ к базе данных
  • Контроллер: контролируйте поток вашего сайта (я знаю, что есть лучшие намерения)

это означает, что если вы видите Linq в качестве основной бизнес-логики, то это НЕ должно быть ни в одном из 2. я бы создал ProductService, который содержит все эти абстрактные вызовы, так как они будут часто использоваться повторно.

что должно быть в Сервисе:

from p in productsRepository
                    where p.PublishedOn != null 
                    orderby p.ProductId descending 
                    select to(p))

что должно быть в контроллере:

from p in productService.GetLatestPublishedProducts()
                    .Skip((page  - 1) * pageSize)
                    .Take(pageSize)

И, если возможно, использовать IEnumerable. нет списка.

1 голос
/ 16 июля 2010

Постарайтесь, чтобы ваши контроллеры были худыми. Это поможет навести порядок. Используйте репозитории для обработки всей логики доступа к данным. Я также включаю сервисный уровень для обработки другой бизнес-логики и логики проверки. Таким образом, мои методы контроллера, службы и репозитория, такие как Create, будут выглядеть так:

// Controller
public ActionResult Create(MyModel myModel)
{
    if (!_service.CreateMyModel(myModel)) 
    {
        return View(myModel);
    }

    return RedirectToAction("Index");
}

// Service
public bool CreateMyModel(MyModel myModel)
{
    // Validation logic
    if (!ValidateMyModel(myModel))  
    {
        return false;
    }

    return _repository.CreateMyModel(myModel);
}

// Repository
public book CreateMyModel(MyModel myModel)
{
    _entities.AddToMyModelsSet(myModel);
    try
    {
        _entities.SaveChages();
        return true;    
    }
    catch
    {
        return false;
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...