哈Ha我想谈谈上图中放置存储库的位置。有关DIP,IoC和项目结构的更多信息。有一种标准方法,根据该标准方法,必须在域层中阻止IRepository接口与DomainServices以及基础结构中的实现。在这里,我们谈论的是标准存储库,它们只是对象的抽象集合,不了解事务和UnitOfWork等(例如,IList及其通用版本是抽象存储库的典型接口)。我个人不同意他的观点,因为通常存储库会被特定于特定应用程序的行为所淹没,因此我将其接口添加到ApplicationServices中。当然,实施仍保留在基础结构层中。如果您有兴趣,那就欢迎猫。罗伯特·马丁(Robert Martin)的旧照片常常使许多人感到困惑:
他在文章中写了几句话实体封装了企业范围的业务规则。实体可以是带有方法的对象,也可以是一组数据结构和函数。只要实体可以被企业中的许多不同应用程序使用,都没有关系。
因此,事实证明,它只是将DomainServices分配给Entities层。好吧,UseCases == ApplicationServices。网关== UserPepository,EmailService,Logger。在这里阅读更多。- 服务是任何无状态的类。InfrastructureService是一个反腐败层,可将您与文件系统,用于SMTP的库以及与ORM或用于数据库的库等隔离。
- Repository . . List Repository T[] ValueObject Entities. Repository InfrastructureService InfrastructureService Repository. : Logger, EmailSender.
- Repository InfrastructureService - EmailSender EmailService, FileService ( File.Open(… ) . .) .
要了解将抽象放置在何处,我们需要考虑依赖反转和控制反转。根据他们的说法,我们的ApplicationService可以使用基础架构,但我不知道它的实现方式如下:- 定义将实现基础结构并与其交互的接口。
- 只需接受Action和Func之类的代表即可。
通过接口: interface IRepository
{
int Get();
}
class ApplicationService
{
private readonly IRepository _repository;
public ApplicationService(IRepository repository)
{
_repository = repository;
}
public int GetInt() => _repository.Get();
}
通过代表: class ApplicationService
{
private readonly Func<int> _getIntFromDb;
public ApplicationService(Func<int> getIntFromDb)
{
_getIntFromDb = getIntFromDb;
}
public int GetInt() => _getIntFromDb();
}
现在介绍如何构建代码。有两种情况需要考虑:- 一切都分为文件夹。
- 一切都分为库。
可以在此处找到术语的详细信息。同一应用程序中的文件夹
SnakeGame代码示例
按图书馆
我们将InfrastructureServices(IRepository)接口放在ApplicationServices库中,并将实现(Repository)放在Infrastructure库中。具有比我的开发经验更多的开发人员
的文章的最终图片,他还认为IRepository应该放置在ApplicationServices的Application Layer中(Repository实现本身也具有Infrastructure)。
发现
可以将基础结构服务接口(IRepository,IEmailSender)放置在ApplicationServices.dll库中,并将它们的特定实现(资源库,EMailSender)放置在Infrastructure.dll库中。