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.
在不同的任务上启动该工作
我是使用 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.
在不同的任务上启动该工作