DDD,存储库和角色接口

时间:2011-05-19 14:22:07

标签: nhibernate domain-driven-design roles ddd-repositories

我非常感谢人们对以下设计问题的看法。

我有一个模型,其中“人”或“商家”可能是某个“服务”的提供者。示例类定义如下所示:

IProvider
Guid Id

人:IProvider
Guid Id
string FirstName
string LastName

商家:IProvider
Guid Id
string 名称

服务
Guid Id
IProvider 提供商

因此,我在我的域名中创建了相关概念,“人物”,“商业”,“IProvider”和“服务”。我正在努力的地方是在哪些实体上创建存储库。在此上下文中,“服务”是聚合根,因此具有自己的存储库。 “业务”也是我的上下文中的聚合根,因为即使它不是提供者,它也具有意义。 “人员”只有在他们“是提供者”的情况下才会在系统中创建。

我是否会为IProvider的角色创建一个存储库,它会返回'Person'和'Business'的实例;我的问题是代码可能很快变得非常复杂,因为任何实现都需要查看多个表等以返回所有不同类型的IProvider。这种方法需要创建“人员”和“业务”的存储库,并将其注入“IProvider”存储库以提供所需的功能,即

public class ProviderRepository : IProviderRepoistory
{
    public IBusinessRepository businessRepository {get; set; }
    public IPersonRepository personRepository {get; set; }

    public IProvider FindById(Guid Id){
        IProvider entity = businessRepository.FindById(Id);

        if(entity == null)
            entity = personRepository.FindById(Id);

        return entity;
    }
}

另一个appraoch将是为实现'IProvider'接口的'Person'和'Business'实体创建存储库,从而使它们可以参与该角色。即

public class PersonRepository : IPersonRepository, IProviderRepository
{
    private ISession session;        

    public Person FindById(Guid Id){
        return session.Query<Person>().FirstOrDefault<Person>(x => x.Id == Id);
    }

    public IProvider FindById(Guid Id){
        return session.Query<Person>().FirstOrDefault<Person>(x => x.Id == Id && x.IsProvider == true);
    }
}

然后我会使用机械(即IoC容器)在需要时选择正确的IProviderRepository实现。例如,如果我正在处理一个我知道是一个人的提供者,我可以获得PersonRepository实现。

另一个选择是不实现任何IProvider存储库,只需坚持使用'Person'和'Business'存储库并在服务层中根据需要使用它们?

1 个答案:

答案 0 :(得分:0)

我认为你已经过度思考了,而且你想要过早地进行优化。

从你在这里所说的一切来看,听起来像个人和商​​业都是实体,但两者都不是一个聚合(尽管很明显,我可能会在与你的领域专家的讨论中遗漏一些东西)。在我看来,提供者是聚合。

当您构建ProviderRepository时,您不需要为企业nad Persons注入存储库,如果它们不是聚合,则b / c不应该拥有自己的存储库。相反,ProviderRepository应该直接使用Session来从您提出的任何数据库模式中获取所需的内容,以便为给定查询组合相关实体。如果正确映射继承,则可以对基类或接口执行查询。