2015-11-07 92 views
0

我一直在尝试学习服务层和存储库模式是如何工作的。到目前为止,我已经写了一个服务层和一个简单的存储库模式接口。但是,我经常看到一些文章指出,存储库模式允许在不消耗代码的情况下更换不同的数据存储库。使用存储库模式提供对不同数据存储的访问

在我的情况下,我希望能够支持读取和写入应用程序数据到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服务的不同服务吗?

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

+1

你的服务的构造函数应该接受一个'IProductRepository'。现在你的服务对象将由'ProductCsvRepository'或'ProductXmlRepository'构成。在运行时,您可以发送两者中的任意一个来执行“IProductRepository”操作。 – singsuyash

回答

2

查看依赖注入和插件模式。他们支持注入一个存储库的具体实现。您的服务层然后只有一个参考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控制容器的反转。这些框架可用于将抽象类(IProductRepository)链接到基于xml配置的具体类(ProductXmlRepositoryProductXmlRepository)。

0

您的应用程序的解决方案应该遵循依赖倒置原则(http://deviq.com/dependency-inversion-principle/)来构建的,因此有最低的三个项目:

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

所有(或几乎所有)接口应该在Core中声明(例如IProductRepository)。您的接口实现属于引用Core的基础架构。最后,你的UI项目应该引用Core,但不一定是基础设施(学习如何使用项目中的类型而不参考它:http://blog.falafel.com/use-types-from-project-without-referencing/)。使用此体系结构,可以使用依赖注入(http://deviq.com/dependency-injection/)在运行时注入给定类型的所需实现,这提供了极大的灵活性和可测试性。

由于传统的UI->业务层 - >数据层设置不允许您反转依赖关系,所以使用此方法成功设置解决方案并保证项目之间的适当依赖关系是至关重要的。一旦以这种方式设置了解决方案,您应该在所有UI和服务代码中遵循显式依赖关系原则(http://deviq.com/explicit-dependencies-principle/)。