c# - 存储库和服务设计问题

标签 c# domain-driven-design service repository-pattern

我们正在尝试找出使用 DDD 时的最佳实践,并且我们正在就什么最有意义或“正确的方法”进行一些讨论。

注意:所有代码均为伪代码。

考虑以下几点:

public interface IDomainEntityAService
{
    void CreateMyObject(DomainEntityA myobject);
    DomainEntityA RetrieveDomainEntityA(long someId);
    //Other operations that handle the business logic dealing with MyObject
}

我们还有另一项服务,它使用 IDomainEntityAService 的一部分来满足特殊需求。

public interface IDomainEntityBService
{
    DomainEntityB GetDomainEntityB();
}

OtherInformation 包含以下内容:

public class DomainEntityB
{
    public string Name { get; set; }
    public IList<DomainEntityA> DomainEntityAList { get; set; }
}

现在我们的问题来了。我们正在研究使用存储库来保存 OtherInformation,如下所示:

public interface IDomainEntityBRepository
{
    void Add(DomainEntityB information);
    DomainEntityB Get(long someId);
}

由于我们希望尽可能保持 DRY 状态,因此理想情况下我们希望重用 IDomainEntityAService 的逻辑来检索 DomainEntityB 的 DomainEntityAList 列表。哪一个最有意义?

A) 在 IDomainEntityBRepository 中引用 IDomainEntityAService 例如

public class SqlDomainEntityBRepository : IDomainEntityBRepository
{

    public SqlDomainEntityBRepository(IDomainEntityAService domainEntityAService, Database database)
    {

    }

    public void Add(DomainEntityB information)
    {
        //save DomainEntityB to SQL
    }
    public DomainEntityB Get(long someId)
    {
        //Get OtherInformation.Name from SQL
        //use domainEntityAService.Get() to populate the list of DomainEntityAList
        //return DomainEntityB
    }
}

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

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; }
}

然后我们将有一个存储库来检索 OtherInformationDAL,然后代码将如下所示:

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;
    }
}

D) 哇,我们完全偏离了基地,而是这样做!!!

我希望这是有道理的,感谢您的帮助。

编辑笔记:

也许英文描述可以帮助更好地描述我的问题。我们有 DomainEntityA,它是一个聚合根。有一个相应的服务来处理与 DomainEntityA 打交道的所有逻辑。

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

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

在 DomainEntityBService 中重用 DomainEntityAService?
在 DomainEntityBService 中创建一个单独的 DomainEntityARepository?

我们目前使用 EntLib,但正在寻找更多关于设计的信息,然后是 DAL 实现。

最佳答案

要不你改用一个让你插入类型的通用接口(interface)怎么样?像这样:

public interface IRepository<T>
{
    T Get(object id);
    void Save(T value);
    void Update(T value);
    void Delete(T value);
    IList<T> GetAll();
}

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

关于c# - 存储库和服务设计问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2313163/

相关文章:

domain-driven-design - DDD 使用规范模式进行验证

domain-driven-design - DDD中的数据访问?

windows - 从 Windows 8 中的 Windows 服务( session 0)向登录屏幕发送输入或类似内容

c# - 如何使用 JSON.NET 确保字符串是有效的 JSON

c# - 按路径加载 XML 文件

c# - EF 代码优先 : Should I initialize navigation properties?

postgresql - Reporting Services - 连接字符串和参数

android - 使用网络服务发现时注册失败,错误代码为 0。

javascript - 在脚本区域中访问的 C# 方法无法识别我的 jQuery 参数

c# - 需要帮助将包含空格的 bbcode URL 转换为有效的 Markdown