Что принадлежит в хранилище, а что нет? - PullRequest
6 голосов
/ 19 августа 2009

В приложении ASP.NET MVC, реализующем шаблон репозитория, мне любопытно, уместно ли размещать не связанные с данными методы в репозитории, если они все еще относятся к общему направлению данного репозитория. Например, предположим, что ProductsRepository имеет методы для добавления и удаления ProductImages, которые имеют частичное представление в базе данных, а также в локальном файловом хранилище. Если необходимо удалить ProductImage, нам нужно удалить строку из базы данных с помощью метода репозитория, а также нам нужно удалить файлы, связанные с этим образом, с носителя. Принадлежат ли операции ввода-вывода в хранилище или есть более подходящее место?

Одна вещь, которую я делал в ситуации, подобной той, которую я только что описал, - это предоставление статических методов в моем хранилище, которые дают мне путь к данному ProductImage, используя имя файла, хранящееся в базе данных, и предопределенный шаблон каталога программно генерировать его. Это за пределами предполагаемого использования хранилища?


Редактировать

Если такая операция не относится к репозиторию, куда должно идти что-то подобное в шаблоне MVC? Мне кажется, что может иметь смысл иметь еще один слой между контроллером и репозиторием, который при необходимости вызывает репозиторий и может вызываться статически из контроллера.

Ответы [ 3 ]

3 голосов
/ 19 августа 2009

Я думаю, что большее беспокойство по поводу модели хранилища связано с тем, что вы нарушаете принцип единой ответственности. Ваш класс должен нести одну ответственность, например, манипулировать данными в базе данных. У вас должна быть другая классовая сделка с File IO, и вы можете сгруппировать функции в класс на один уровень вверх.

Должна быть только одна причина для изменения класса, а класс репозитория, который обрабатывает файловый IO и вызовы db, будет иметь две. Изменение структуры файловой системы или базы данных.

Редактировать

Чтобы ответить на ваш вопрос редактирования, вот как я мог бы реализовать это в сценарии MVC (это также предполагает, что вы используете какое-то внедрение зависимости, чтобы облегчить жизнь).

// Controller class
public class ProductsController
{
    private IProductService _productService;

    public ProductsController(IProductService productService)
    {
        _productService = productService
    }

    public void RemoveImage(int productId, int imageId)
    {
        _productService.RemoveImage(productId, imageId)
    }
}

public class ProductService: IProductService
{
    private IProductRepository _productRepository;
    private IProductImageManager _imageManager;

    public ProductService(IProductRepository productRepository, IProductImageManager imageManager)
    {
      _productRepository = productRepository;
      _imageManager = imageManager;
    }

    public void RemoveImage(int productId, int imageId)
    {
        // assume some details about locating the image are in the data store
        var details = _productRepository.GetProductImageDetails(productId, imageId);
        // TODO: error handling, when not found?
        _imageManager.DeleteImage(details.location);
        _productRepository.DeleteImage(productId, imageId)
    }
}

Затем вы реализуете IProductImageManager и IProductRepository на основе любого интерфейса, который имеет смысл с конкретными реализациями для ваших конкретных потребностей.

2 голосов
/ 19 августа 2009

Я недавно разработал новый репозиторий и боролся с тем же вопросом.Я закончил тем, что включил свои дополнительные методы в хранилище.

Оглядываясь назад сейчас, я чувствую, что лучшим решением было бы сделать мой репозиторий более сфокусированным и поместить мои дополнительные методы в Сервискоторый тесно интегрирован с моим репозиторием.

В приведенном выше примере у вас может быть метод «DeleteProductImage» в ProductsService, который будет вызывать ProductsRepository.DeleteImage, а также обрабатывать удаление изображений с носителя.

Это обеспечивает чистоту вашего хранилища и фокусируется только на логике «DeleteImage», в то же время предоставляя вам единственный метод, который вам нужно вызвать («DeleteProductImage»), который заботится о вызове хранилища для удаления изображения, а также обрабатывает взаимодействие с ним.носитель данных и любые другие вещи, которые могут потребоваться при удалении образа, которые не имеют прямого отношения к вашему хранилищу.

1 голос
/ 19 августа 2009

Хранилище предназначено для того, чтобы изолировать приложение от проблем, связанных с тем, как и где хранятся данные, которые он потребляет. Исходя из этого, хранилище является абсолютно подходящим местом для обработки как базы данных, так и файловых операций в этом контексте.

...