3

我从TDD的角度清楚了解存储库模式及其重要性。我也明白,为应用程序切换底层数据存储是多么容易,因为存储库充当数据访问逻辑的窗口。如何在存储库模式中为相同接口使用两个数据存储?

我没有得到的是如何同时支持多个数据存储。下面是一个例子,假设我已经定义了一个存储库IPersonRepository,它有两个实现,并且需要读取XML文件并存储到SQL数据库中,反之亦然。

DataAccessLayer

public interface IPersonRepository 
{ 
    Person GetPersonById(int id); 
} 

public class PersonRepositorySQL : IPersonRepository 
{ 
    public Person GetPersonById(int id) 
    { 
     // get person from sql db (using ado.net) 
    } 
} 

public class PersonRepositoryXML : IPersonRepository 
{ 
    public Person GetPersonById(int id) 
    { 
     // get person from xml file 
    } 
} 

BusinessLogicLayer

public PersonService 
{ 
    private IPersonRepository personRepository; 

    public PersonService(IPersonRepository personRepository) 
    { 
     this.personRepository = personRepository; 
    } 

    public Person GetPersonById(int id) 
    { 
     personRepository.GetPersonById(id); 
    } 
} 

问题(按重要性排序):

  1. 这是否意味着我必须实例2 PersonService对象每次通过分别传递PersonRepositorySQL和PersonRepositoryXML来从db和xml读取数据?
  2. 为了达到上述目的,我必须添加对上层存储库(主要是演示文稿)的引用?这怎么可以避免?
  3. DAL是否是保存存储库的好地方?
  4. 可以将BLL类命名为Service ex:PersonService?

我意识到帖子变得很长,但我想把所有引起混淆的东西都记在脑后。

- NV

回答

2

这是否意味着我必须实例2 PersonService对象为分别通过PersonRepositorySQL和PersonRepositoryXML从数据库和XML读取数据每次?

不,但您正朝着正确的方向前进。我将两个存储库注入服务(两个构造函数参数)并编写两个服务方法,一个以另一种方式一种方式移动数据。

连接两个存储库而不是客户端应该是服务的责任。

然后使用IoC容器来设置服务实例并将其提供给客户端,并且肯定不推荐使用New Services()。您需要查看适用于您所使用的任何演示技术的IoC工具/方法。

为了达到上述目的,我必须添加对上层存储库(主要是演示文稿)的引用?这怎么可以避免?

没关系呈现,因为它需要知道如何注入到服务实例,介绍是只需要直接和仅因该理由引用具体DAL类的地方。

我发现谷歌的VS分层架构项目结构(或类似)帮助我堆回来,当我不太确定。

DAL是否是保存存储库的好地方?

这就是他们应该在的地方。您的DAL通常用于涉及硬件的所有内容,例如文件,dbs和webapis。

是否可以将BLL类命名为Service ex:PersonService?

绝对。它很简短,很好,告诉人们(和其他开发人员)它是什么(服务),它的职责是(人)

0

只是为了解决问题1:不是实例化两个服务,而是实例化一个服务并通过一个Composite进去。为此,你需要一个CompositeRepositoryFactory类型来创建合适的Composite。请注意,更多的是

一点关于综合和你的具体情况:

  • 它可以让你把多个的实现,同时在客户端保持原来的接口的引用。
  • 允许您链接同一接口的多个实现。通过这种方式,实现可以级联方法调用,从而实现更丰富的逻辑。另一方面,客户端维护所需的依赖关系:仅在接口本身。
  • 复合图案有利于SRP原则:如果你的课程太广泛并且有很大的界面,你将无法修饰它,因为: 精确地实施装饰会很困难(因为课堂做得太多) 。
  • 如下图所示:客户端提供CompositeComponent(通过IComponent参考变量)。 CompositeComponent引用另一个IComponent实现(例如ConcreteComponent),它自己的一些逻辑在Something()之内,然后作为该逻辑的一部分 - 它调用ConcreteComponent.Something()。通过这种方式,最初致电CompositeComponent.Something()级联到ConcreteComponent

Composite Repository diagram

  • 我还创建了上述数字可能如何适用于你的情况下快速图:您的客户端代码继续使用PersonService,但的而不是在一些IPersonRepository实现直接传递,你首先要去PersonCompositeRepositoryFactory。在分辨率根侧必要的唯一变化是使用PersonCompositeRepositoryFactory

enter image description here