存储库和服务层之间的区别?
在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库中的几个,而那些我一直坚持这个原则的库可以在几分钟内取代。 我在哪里有一些逻辑,而不是几个小时。
通常一个存储库被用作脚手架来填充你的实体 – 一个服务层会出去请求。 很可能你会把一个仓库放在你的服务层下面。