.NET Core API洋葱架构中限制领域实体访问的方案咨询
解决方案:阻止API层访问领域实体,强制使用DTO
以下是几种可行的方案,从简单实现到严格架构控制分级呈现:
方案一:禁用应用层到领域层的传递引用(最简便)
无需修改任何类型访问修饰符,仅通过项目引用配置实现隔离:
- 在应用层的csproj文件中,修改对领域层的项目引用,添加
PrivateAssets="all"阻止引用传递到API层:
<ItemGroup> <ProjectReference Include="..\YourApp.Domain\YourApp.Domain.csproj" PrivateAssets="all" /> </ItemGroup>
- 确保API层仅引用应用层,不直接引用领域层。
- 此时API层无法访问领域层的任何公开类型(包括领域实体),只能通过应用层暴露的DTO完成交互。
方案二:用InternalsVisibleTo精准授权+调整基础设施层访问级别
如果需要更严格的实体访问控制(比如限制应用层直接修改实体),可以将领域实体设为internal,仅授权给必要层级:
- 在领域层的csproj中,添加对应用层和基础设施层的内部访问授权:
<ItemGroup> <!-- 允许应用层访问领域层内部类型 --> <AssemblyAttribute Include="System.Runtime.CompilerServices.InternalsVisibleTo"> <_Parameter1>YourApp.Application</_Parameter1> </AssemblyAttribute> <!-- 允许基础设施层访问领域层内部类型 --> <AssemblyAttribute Include="System.Runtime.CompilerServices.InternalsVisibleTo"> <_Parameter1>YourApp.Infrastructure</_Parameter1> </AssemblyAttribute> </ItemGroup>
- 调整基础设施层的DbSet访问级别为
internal(因为MyEntity是internal,无法绑定到public属性):
internal DbSet<MyEntity> MyEntities { get; set; }
若使用EF Core迁移工具,需额外给迁移项目添加授权(若迁移单独部署在项目中):
<AssemblyAttribute Include="System.Runtime.CompilerServices.InternalsVisibleTo"> <_Parameter1>YourApp.Infrastructure.Migrations</_Parameter1> </AssemblyAttribute>
- 仓储契约(如
IMyEntityRepository)保持public,应用层因授权可正常使用,API层无授权则无法访问MyEntity。
方案三:通过领域服务封装实体访问(架构更贴合洋葱设计)
从洋葱架构的核心思想出发,应用层不应直接操作领域实体,需通过领域服务完成交互:
- 领域层:将实体设为
internal,定义public的领域服务,服务仅接收/返回领域DTO(领域层内部定义的公开DTO)。 - 应用层:依赖领域服务,将领域DTO转换为API层所需的DTO后传递给API层。
- 基础设施层:通过
InternalsVisibleTo授权访问领域实体,DbSet和仓储实现可正常工作。 - API层完全无法接触到领域实体,只能使用应用层提供的API DTO。
内容的提问来源于stack exchange,提问作者peelaazgar
相关产品推荐
相关产品推荐

