这是DTO的正确使用吗?

时间:2011-06-10 18:10:41

标签: c# .net entity-framework domain-driven-design dto

我正在编写一个控制台应用程序,它可以从存储过程记录集中执行大量数据检索。对于我正在使用的每个记录集类型,我有一个使用EF和自定义复杂类型的存储库来检索数据:

public interface IBalanceSheetRepository
{
    IEnumerable<BalanceSheetRecordDTO> GetBalanceSheetRecords();
}

public class BalanceSheetRepository : IBalanceSheetRepository
{
    DBContext _context;

    ...

    public IEnumerable<BalanceSheetRecordDTO> GetBalanceSheetRecords()
    {
        ObjectResult<BalanceSheetRecord> results = _context.GetBalanceSheet();
        return results.Select(CreateBalanceSheetDTOFromDAO);
    }

    private static BalanceSheetRecordDTO CreateBalanceSheetDTOFromDAO(BalanceSheetRecord dao)
    {
        return new BalanceSheetRecordDTO { ... };
    }
}

这里,BalanceSheetRecord是我在设计器中创建的复杂数据类型。我创建了一个DTO以避免耦合,因为BLL不应该知道BalanceSheetRecord类型。

这是我的问题:由于DTO类型用于存储库接口的方法签名,并且因为我的BLL最终将使用存储库&amp;返回DTO的集合,这似乎是一个贯穿各领域的关注点。因此,我让DTO与repo接口一起生活在一个单独的“Infrastructure”组件中。这是我努力实现的良好做法,还是我在某个地方转错了?

另外:在我的存储库中新建数据上下文是不好的做法?当两个组件都属于DAL时,是否有一定量的耦合?我想使用DI,但是对于交换TestBalanceSheetRepository的repo的DBContext实现似乎更有用。

1 个答案:

答案 0 :(得分:6)

我更喜欢从我的存储库返回实际实体。这样,当您需要协调服务层中不同实体之间的复杂交互时,就不会来回转换到DTO。然后,当将数据返回到应用程序层时,服务层将实体投影到DTO中。

我知道有些纯粹主义者说层之间的所有互动都应该用DTO来完成,但我发现这是不切实际的。无论如何,服务层最终会耦合到实体,所以它不像你正在添加耦合。

它还限制了DTO到实体到服务层的投影/展平。对我来说这是一个加分,因为这些活动增加了复杂性并降低了性能。

您的数据环境是您的工作单位。 “每个存储库的一个工作单元”的想法是一种反模式。工作单元应由服务层确定范围,这可能涉及来自1-many存储库的1-many实体。如果每个存储库具有不同的工作单元,则您将无法轻松地使服务层调用保持一致的事务。