在DDD应用中,这段用户数据处理代码应置于何处?
关于DDD中复用缓存+API同步逻辑的设计建议
核心结论:应用服务是合适的选择,但需做轻量化、无依赖的设计
你的场景完全适合用应用服务封装这段复用逻辑,但要避免把应用服务和Web UI/Job的特定上下文绑定,确保它是独立的业务逻辑单元。
具体设计要点
- 抽离独立的应用服务类:把缓存检查、API获取、仓储同步这三步封装成一个独立的应用服务(比如
UserSyncAppService),依赖IMemoryCache、用户API客户端(比如IUserApiClient)、用户仓储(IUserRepository)这些抽象接口,而非具体实现。这样不管是Web UI还是Web Job,只要注入对应的实现就能直接调用。public class UserSyncAppService : IUserSyncAppService { private readonly IMemoryCache _cache; private readonly IUserApiClient _userApiClient; private readonly IUserRepository _userRepository; public UserSyncAppService(IMemoryCache cache, IUserApiClient userApiClient, IUserRepository userRepository) { _cache = cache; _userApiClient = userApiClient; _userRepository = userRepository; } public async Task SyncUsersAsync() { // 1. 检查缓存 if (_cache.TryGetValue("UserList", out List<UserDto> cachedUsers)) { await SyncToDatabaseAsync(cachedUsers); return; } // 2. 从API获取数据 var apiUsers = await _userApiClient.GetUsersAsync(); // 3. 更新缓存 _cache.Set("UserList", apiUsers, new MemoryCacheEntryOptions { SlidingExpiration = TimeSpan.FromHours(1) }); // 4. 同步到数据库 await SyncToDatabaseAsync(apiUsers); } private async Task SyncToDatabaseAsync(List<UserDto> users) { foreach (var userDto in users) { var existingUser = await _userRepository.GetByIdAsync(userDto.Id); if (existingUser == null) { await _userRepository.AddAsync(MapToEntity(userDto)); } else { UpdateEntity(existingUser, userDto); await _userRepository.UpdateAsync(existingUser); } } await _userRepository.UnitOfWork.SaveChangesAsync(); } // 省略Dto转实体的映射方法 private User MapToEntity(UserDto dto) => /* 映射逻辑 */; private void UpdateEntity(User entity, UserDto dto) => /* 更新逻辑 */; } - 避免上下文耦合:应用服务里不要直接引用Web UI的
HttpContext或者Web Job的JobHost这类特定环境对象,所有依赖都通过抽象接口注入,保证在不同项目中都能适配。 - 拆分职责(可选):如果后续逻辑变复杂,可以把缓存操作、API获取、数据库同步拆成更小的领域服务或基础设施服务,让应用服务只负责编排流程,保持单一职责。比如用
ICacheService封装缓存操作,IUserSyncService封装数据库同步逻辑,应用服务只做流程调度。 - 复用方式:把这个应用服务放在一个独立的类库项目(比如
YourApp.Application)中,Web UI和Web Job项目都引用这个类库,然后通过各自的DI容器注入所需的依赖实现(比如Web UI和Web Job可以共用内存缓存,也可以根据需求换成分布式缓存,只要实现对应的抽象接口)。
为什么应用服务适合这个场景
应用服务的核心职责就是编排业务流程、协调领域对象和基础设施,你的场景刚好是跨基础设施(缓存、API、数据库)的流程编排,而且需要在多个客户端(Web UI、Web Job)复用,完全符合应用服务的设计定位。
内容的提问来源于stack exchange,提问作者user204588
相关产品推荐
相关产品推荐

