6

在实现存储库模式的 ASP.NET MVC 应用程序中,我很好奇如果它们仍然与给定存储库的一般焦点相关,是否适合将非数据相关方法放置在存储库中。例如,假设 ProductsRepository 具有添加和删除 ProductImages 的方法,这些方法在数据库和本地文件存储中也有部分表示。如果需要删除 ProductImage,我们需要使用存储库方法从数据库中删除一行,并且我们还需要从存储介质中删除与该图像关联的文件。IO 操作是否属于存储库,还是有更合适的位置?

在刚刚描述的情况下,我一直在做的一件事是在我的存储库中提供静态方法,这些方法通过使用存储在数据库中的文件名和预定义的目录模式以编程方式生成它,为我提供了给定 ProductImage 的路径. 这超出了存储库的预期用途吗?


编辑

如果这样的操作不属于存储库,那么类似的东西在 MVC 模式中应该放在哪里?在我看来,在 Controller 和 Repository 之间有另一个层可能是有意义的,它根据需要调用 Repository 并且可以从 Controller 静态调用。

4

3 回答 3

4

我认为对存储库模式的更大担忧是您违反了单一责任原则。你的类应该有一个职责,比如操作数据库中的数据。您应该有一个不同的类来处理文件 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。

于 2009-08-19T15:41:03.367 回答
2

我最近设计了一个新的存储库,并为同样的问题而苦苦挣扎。我最终在存储库中包含了我的其他方法。

不过现在回想起来,我觉得更好的解决方案是让我的存储库更加专注,并将我的其他方法放入与我的存储库紧密集成的服务中。

对于上面的示例,您可以在 ProductsService 中使用“DeleteProductImage”方法,该方法将调用 ProductsRepository.DeleteImage,然后还可以处理从存储介质中删除图像。

这使您的存储库保持干净并仅专注于“DeleteImage”逻辑,同时仍为您提供需要调用的单个方法(“DeleteProductImage”),该方法负责调用存储库以删除图像,同时还处理与存储介质的交互以及在删除与您的存储库没有直接关系的图像时可能需要发生的任何其他事情。

于 2009-08-19T15:43:16.047 回答
1

存储库用于将应用程序与其所使用的数据的存储方式和存储位置隔离开来。在此基础上,存储库绝对是在这种情况下处理数据库和基于文件的活动的正确位置。

于 2009-08-19T15:41:07.440 回答