存储库和服务层之间的区别?

在OOPdevise模式中,存储库模式和服务层之间有什么区别?

我正在研究一个ASP.NET MVC 3应用程序,并试图了解这些devise模式,但我的大脑只是没有得到它…但!

存储库层为数据访问提供了额外的抽象级别。 而不是写作

var context = new DatabaseContext(); return CreateObjectQuery<Type>().Where(t => t.ID == param).First(); 

要从数据库中获取单个项目,请使用存储库接口

 public interface IRepository<T> { IQueryable<T> List(); bool Create(T item); bool Delete(int id); T Get(int id); bool SaveChanges(); } 

并调用Get(id) 。 存储库层公开了基本的CRUD操作。

服务层公开使用存储库的业务逻辑。 示例服务可能如下所示:

 public interface IUserService { User GetByUserName(string userName); string GetUserNameByEmail(string email); bool EditBasicUserData(User user); User GetUserByID(int id); bool DeleteUser(int id); IQueryable<User> ListUsers(); bool ChangePassword(string userName, string newPassword); bool SendPasswordReminder(string userName); bool RegisterNewUser(RegisterNewUserModel model); } 

虽然存储库的List()方法返回所有用户,但ListUsers()只能返回一个,用户可以访问。

在ASP.NET MVC + EF + SQL SERVER中,我有这样的通信stream程:

视图< – 控制器 – >服务层 – >存储库层 – > EF – > SQL Server

服务层 – >存储库层 – > EF这部分在模型上运行。

视图< – 控制器 – >服务层这部分操作视图模型。

编辑:

/ Orders / ByClient / 5的stream程示例(我们希望看到特定客户端的订单):

 public class OrderController { private IOrderService _orderService; public OrderController(IOrderService orderService) { _orderService = orderService; // injected by IOC container } public ActionResult ByClient(int id) { var model = _orderService.GetByClient(id); return View(model); } } 

这是订单服务的界面:

 public interface IOrderService { OrdersByClientViewModel GetByClient(int id); } 

这个接口返回视图模型:

 public class OrdersByClientViewModel { CientViewModel Client { get; set; } //instead of ClientView, in simple project EF Client class could be used IEnumerable<OrderViewModel> Orders { get; set; } } 

这是接口的实现。 它使用模型类和存储库来创build视图模型:

 public class OrderService : IOrderService { IRepository<Client> _clientRepository; public OrderService(IRepository<Client> clientRepository) { _clientRepository = clientRepository; //injected } public OrdersByClientViewModel GetByClient(int id) { return _clientRepository.Get(id).Select(c => new OrdersByClientViewModel { Cient = new ClientViewModel { ...init with values from c...} Orders = c.Orders.Select(o => new OrderViewModel { ...init with values from o...} } ); } } 

正如Carnotaurus所说,存储库负责将数据从存储格式映射到业务对象。 它应该同时处理如何从存储器读取和写入数据(删除,更新)。

另一方面,服务层的目的是将业务逻辑封装到一个地方,以促进代码重用和关注的分离。 在构buildAsp.net MVC站点时,这对我来说通常意味着什么,就是我有这个结构

[Controller]调用[repository(iies)]的[Service(s)]

我发现一个有用的原则是在控制器和存储库中保持逻辑最小化。

在控制器中,这是因为它有助于保持干爽。 我常常需要在别的地方使用相同的filter或逻辑,如果我把它放在控制器中,我不能再使用它。

在存储库中,这是因为我希望能够在出现更好的情况时replace存储(或ORM)。 如果我在存储库中有逻辑,当我更改存储库时,我需要重写这个逻辑。 如果我的存储库只返回IQueryable,而服务执行过滤,我将只需要replace映射。

例如,我最近用EF4replace了我的Linq-To-Sql库中的几个,而那些我一直坚持这个原则的库可以在几分钟内取代。 我在哪里有一些逻辑,而不是几个小时。

通常一个存储库被用作脚手架来填充你的实体 – 一个服务层会出去请求。 很可能你会把一个仓库放在你的服务层下面。