【问题标题】:Providing access to different data stores with the Repository Pattern使用存储库模式提供对不同数据存储的访问
【发布时间】:2015-11-07 11:02:58
【问题描述】:

我一直在尝试了解服务层和存储库模式的工作原理。到目前为止,我已经编写了一个服务层和一个简单的存储库模式接口。但是,我经常看到一些文章指出,存储库模式允许在无需更改使用代码的情况下交换不同的数据存储。

就我而言,我希望能够支持将应用程序数据读取和写入 CSV 和/或 XML 文件。这是我不明白如何使用存储库模式正确实现这一点的部分。每个数据存储是否应该有一个存储库?

ProductCsvRepository : IProductRepository
ProductXmlRepository : IProductRepository

但是,如果我这样做,则服务层必须了解底层数据存储,这打破了能够轻松换入和换出不同数据存储的想法。

然后我是否必须有一个看起来像这样的服务层?

private readonly IProductXmlRepository _productXmlRepository;
private readonly IProductCsvRepository _productCsvRepository;

public ProductService()
{
    _productXmlRepository = new IProductXmlRepository();
    _productCsvRepository = new IProductCsvRepository();
}

public ICollection<Product> GetAllXml()
{
    return _productXmlRepository.GetAllCsv();
}

public ICollection<Product> GetAll()
{
    return _productCsvRepository.GetAllXml();
}

这就引出了两个问题:

  • 这肯定会打破消费代码需要知道数据存储是什么的想法吗?
  • 在消费代码确实需要了解数据存储的情况下,例如“文件 > 导出为”类型的功能怎么办?导出功能实际上应该是使用适当 CSV 或 XML 服务的不同服务吗?

我想我肯定不明白如何正确实现存储库模式和服务层。我应该如何实际设计存储库模式和服务层?

【问题讨论】:

  • Service 的构造函数应该接受IProductRepository。现在您的服务对象将由ProductCsvRepositoryProductXmlRepository 组成。在运行时,您可以发送两者中的任何一个来执行IProductRepository 操作。

标签: c# .net oop design-patterns software-design


【解决方案1】:

看看依赖注入和插件模式。他们支持注入存储库的具体实现。然后,您的服务层只有一个对 IProductRepository 的引用,并且注入了一个具体的存储库。类似这样的东西:

public class ProductService
{
    private readonly IProductRepository _productRepository;

    public ProductService(IProductRepository productRepository)
    {
        _productRepository = productRepository;
    }
}


public class ConsumingClass {
{
    private readonly IProductService _productService = new ProductService(new ProductXmlRepository());

    // methods to use the the product service
}

但更好的是使用控制容器的反转,如 NInject 或 SimpleInjector。这些框架可用于基于 xml 配置将抽象类 (IProductRepository) 链接到具体类(ProductXmlRepositoryProductXmlRepository)。

【讨论】:

    【解决方案2】:

    您的应用程序解决方案的结构应遵循依赖倒置原则 (http://deviq.com/dependency-inversion-principle/),以便至少有三个项目:

    • 核心
    • 基础设施
    • 您的 UI 项目

    所有(或几乎所有)接口都应在 Core 中声明(例如 IProductRepository)。您的接口实现属于引用核心的基础设施。最后,您的 UI 项目应该引用 Core,但不一定要引用 Infrastructure(了解如何使用项目中的类型而不引用它:http://blog.falafel.com/use-types-from-project-without-referencing/)。

    有了这个架构,您可以使用依赖注入 (http://deviq.com/dependency-injection/) 在运行时注入给定类型的所需实现,这提供了极大的灵活性和可测试性。

    使用项目之间的正确依赖关系设置您的解决方案对于使用这种方法取得成功至关重要,因为传统的 UI -> 业务层 -> 数据层设置不允许您反转依赖关系。以这种方式设置解决方案后,您应该在所有 UI 和服务代码中遵循显式依赖原则 (http://deviq.com/explicit-dependencies-principle/)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-12-15
      • 1970-01-01
      • 2011-10-01
      • 2023-03-27
      • 2023-03-20
      • 1970-01-01
      相关资源
      最近更新 更多