这是DTO的正确使用吗?

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

public interface IBalanceSheetRepository { IEnumerable GetBalanceSheetRecords(); } public class BalanceSheetRepository : IBalanceSheetRepository { DBContext _context; ... public IEnumerable GetBalanceSheetRecords() { ObjectResult results = _context.GetBalanceSheet(); return results.Select(CreateBalanceSheetDTOFromDAO); } private static BalanceSheetRecordDTO CreateBalanceSheetDTOFromDAO(BalanceSheetRecord dao) { return new BalanceSheetRecordDTO { ... }; } } 

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

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

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

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

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

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

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