Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/260.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 存储库和服务设计问题_C#_Domain Driven Design_Service_Repository Pattern - Fatal编程技术网

C# 存储库和服务设计问题

C# 存储库和服务设计问题,c#,domain-driven-design,service,repository-pattern,C#,Domain Driven Design,Service,Repository Pattern,我们正在努力找出使用DDD时的最佳实践,我们正在就什么最有意义或是“正确的方式”进行一些讨论 注意:所有代码都是伪代码。 承认者如下: public interface IDomainEntityAService { void CreateMyObject(DomainEntityA myobject); DomainEntityA RetrieveDomainEntityA(long someId); //Other operations that handle the

我们正在努力找出使用DDD时的最佳实践,我们正在就什么最有意义或是“正确的方式”进行一些讨论

注意:所有代码都是伪代码。

承认者如下:

public interface IDomainEntityAService
{
    void CreateMyObject(DomainEntityA myobject);
    DomainEntityA RetrieveDomainEntityA(long someId);
    //Other operations that handle the business logic dealing with MyObject
}
public class DomainEntityB
{
    public string Name { get; set; }
    public IList<DomainEntityA> DomainEntityAList { get; set; }
}
public class DomainEntityBService : IDomainEntityBService
{

    public DomainEntityBService(IDomainEntityAService domainEntityAService, IDomainEntityBRepository repo)
    {
    }
    public DomainEntityB GetDomainEntityB()
    {

        var domainEntityBDAL = _repo.Get(someId);
        DomainEntityB result = new DomainEntityB() { Name = domainEntityBDAL.Name };
        foreach (var id in domainEntityBDAL.DomainEntityAListIds)
        {
            result.DomainEntityAList.Add(_domainEntityAService.Get(id));
        }
        return result;
    }
}
我们还有另一个服务,它使用IDomainEntityAService的一部分来满足特定的需求

public interface IDomainEntityBService
{
    DomainEntityB GetDomainEntityB();
}
其中,其他信息包含以下内容:

public interface IDomainEntityAService
{
    void CreateMyObject(DomainEntityA myobject);
    DomainEntityA RetrieveDomainEntityA(long someId);
    //Other operations that handle the business logic dealing with MyObject
}
public class DomainEntityB
{
    public string Name { get; set; }
    public IList<DomainEntityA> DomainEntityAList { get; set; }
}
public class DomainEntityBService : IDomainEntityBService
{

    public DomainEntityBService(IDomainEntityAService domainEntityAService, IDomainEntityBRepository repo)
    {
    }
    public DomainEntityB GetDomainEntityB()
    {

        var domainEntityBDAL = _repo.Get(someId);
        DomainEntityB result = new DomainEntityB() { Name = domainEntityBDAL.Name };
        foreach (var id in domainEntityBDAL.DomainEntityAListIds)
        {
            result.DomainEntityAList.Add(_domainEntityAService.Get(id));
        }
        return result;
    }
}
因为我们希望尽可能地保持干燥,所以理想情况下我们希望重用IDomainEntityAService的逻辑来检索DomainEntityB的DomainEntityList列表。哪一个最有意义

A) 在IDOMainEntityBreposition中引用IDomainEntityAService e、 g

B) IDomainEntityBRepository只处理SQL内容,我们使用IHaveOtherInformation的服务层来填充MyObject列表

public class DomainEntityBService : IDomainEntityBService
{
    public DomainEntityBService(IDomainEntityAService domainEntityAService, IDomainEntityBRepository repo)
    {
    }
    public DomainEntityB GetDomainEntityB()
    {
        var domainEntityB = _repo.Get(someId);
        domainEntityB.DomainEntityAList = _domainEntityAService.GetAll(someId);
        return domainEntityB;
    }
}
C) 我们为OtherInformation创建一个特定的DAL对象,并使用服务层来组成OtherInformation的实例

public class DomainEntityBDAL
{
    public string Name { get; set; }
    public IList<int> DomainEntityAListIds { get; set; }
}
D) 哇,我们完全偏离了底线,请改为这样做

我希望这是有意义的,谢谢你的帮助

编辑注释:

public interface IDomainEntityBRepository
{
    void Add(DomainEntityB information);
    DomainEntityB Get(long someId);
}
也许一个英文描述能更好地描述我的问题。我们有DomainEntityA,它是一个聚合根。有一个相应的服务来处理处理DomainEntityA的所有逻辑

现在我们还有DomainEntityB,它是一个聚合根。但是,DomainEntityB有一个DomainEntityA列表。DomainEntityAs可以独立生存,但是DomainEntityB不能没有DomainEntityAs列表

我们如何在DomainEntityB中加载DomainEntityA项列表并维护DomainEntityA的所有逻辑

在DomainEntityBService中重用DomainEntityAService?
是否在DomainEntityBService中创建单独的DomainEntityARepository


我们目前使用EntLib,但更多的是关于设计的信息,而不是DAL实现的信息。

我在这里假设您将存储到数据库中

这个问题的答案很大程度上取决于您使用什么作为持久性引擎。如果您已经手工实现了自己的持久化,那么
C
就不是一个选项,因为您将看到N+1查询
B
很可能是我的首选,因为它提供了最多的代码重用,希望性能不会太差

话虽如此,如果您使用的是NHibernate之类的东西,我建议您不要使用存储库模式,而是

  • 将复杂查询封装为对象(然后可以进行单元测试)
  • 直接使用会话

我希望这有帮助

不如改用一个通用接口来插入类型?像这样:

public interface IRepository<T>
{
    T Get(object id);
    void Save(T value);
    void Update(T value);
    void Delete(T value);
    IList<T> GetAll();
}
公共接口IRepository
{
T Get(对象id);
无效保存(T值);
无效更新(T值);
无效删除(T值);
IList GetAll();
}

无论使用什么实现,都应该能够读取类型并知道它如何适合数据库。简而言之,这就是存储库模式。如果您还没有完全使用Entlib,请探索NHibernate。我发现它很好地补充了存储库模式。我在我的博客上写了很多文章,所以如果你想知道更多,你可以去那里。

我们很可能会在DAL中使用EntLib。你知道为什么A被认为是不好的吗?存储库返回从多个位置收集的对象是否是一种不好的做法?e、 要创建域模型的实例,我需要从SQL、XML和文件中查询?或者一个存储库应该只涉及一个数据存储?这个问题的答案不应该指导您使用哪个DAL实现吗?为什么你这么热衷于Entlib?如果某个DAL实现能让这变得更容易,我完全赞成。我们过去使用过Entlib,并计划将其与存储库模式一起使用。感谢您提供的信息,不过请参阅我的编辑。如果T的子级也是聚合根(在完全不同的域中),您将如何处理在存储库中加载这些项?NHibernate可以处理“T的子级”(也称为继承)。我不知道你所说的“聚合根在另一个域中”可能是什么意思,但NHibernate可以处理几乎任何你能想到的关系。我不是说继承,“B”有一个“a”的列表。“A”可以独立使用,也可以被其他服务/应用程序使用。现在“B”需要一个“a”的列表才能成为“B”的有效实例。假设要获得所有的“A”(例如“B”)它需要进行一个webservice调用。那个电话应该在哪里?加载“B”的“A”的调用应该在DAL、服务层或其他地方进行吗?B应该只存储一个标识符列表(可能是整数?)。您应该为每个系统创建存储库实现,其中两个实现都继承了IRepository接口。为了详细说明,您将为系统A(使用web服务)提供一个repo,为系统B提供一个repo(使用NHibernate)。您想要两个不同的存储库的原因是将这两个系统解耦,以便在系统A发生更改时,您可以简单地创建其存储库的新版本,而不会干扰系统B的存储库。这在实践中效果很好。