Service/Repository 模式和异步等待 API 的最佳实践

Best practices for Service/Repository pattern and async await APIs

我是使用 Service/Repository 模式的新手。这是我目前的代码:

public interface IRepository<T> where T : class
{
    Task<IEnumerable<T>> GetAll();
}


public interface IUserRepository : IRepository<User>
{

}


public class UserRepository : IUserRepository
    {
        public async Task<IEnumerable<User>> GetAll()
        {
            List<User> lst = new List<User>();
            lst.Add(new User { ID = 1, Code = "001", Username = "dfrancisco", Password = "dfrancisco123" });
            lst.Add(new User { ID = 1, Code = "002", Username = "111", Password = "1231!" });
            lst.Add(new User { ID = 1, Code = "003", Username = "22", Password = "asdasd1!" });
            lst.Add(new User { ID = 1, Code = "004", Username = "334", Password = "asdasd1" });
            lst.Add(new User { ID = 1, Code = "005", Username = "55", Password = "13" });

            return lst;
        }
    }


public class UserService : IUserService
    {
        private readonly IUserRepository _userRepository;

        #region Constructors

        /// <summary>
        /// constructor for UserService
        /// </summary>
        /// <param name="UserRepository"></param>
        public UserService(IUserRepository UserRepository)
        {
            _userRepository = UserRepository;
        }

        public async Task<IEnumerable<UserDTO>> GetAll()
        {
            List<User> data = (await _userRepository.GetAll()).ToList();


            List<UserDTO> dtos = new List<UserDTO>();
            foreach (User item in data)
            {
                dtos.Add(new UserDTO { Username = item.Username });
            }

            return dtos;
           // throw new NotImplementedException();
        }
        #endregion
    }

所以,我想知道这是否是使用这种设计模式的正确方法。我已经在网上看到很多使用此代码以这种方法 return 数据的示例:

return await _repository.GetAll(eppPlanId);

或者这个..

return await Task.Run(() => eppPlanDetails);

我提出的案例只是为了演示所需的随机业务逻辑。所以,我想了解这些方法有什么区别,我应该使用哪种方法。

如果您计划并且您可能应该坚持使用异步 APIs,那么您也应该为所有存储库 APIs 使用它们。有一个命名约定,用 "Async" 为异步方法添加后缀。所以你的方法应该命名为 "GetAllAsync()" 而不是。

至于坚持哪种方法 - 几乎到了关键点,API 是否是异步的。如果 API 是异步的(在你的情况下是异步的),你不需要再调用 Task.Run() :调用 API 时只需使用 await。 如果 GetAll() 是非异步的,您将使用 Task.Run,并且直接 return IEnumerable。在那种情况下,为了不阻塞线程 - 你可以使用 Task.Run.

在不同的任务上启动该工作