Easy implementation of Repository Pattern
我将ADO.NET直接用于MVC 5,而不是实体框架。
我引用这个例子来实现存储库模式。
对于存储库模式的简单实现:
我想知道为什么要使用接口?我不能按照上面第(3)点直接使用类吗?
接口的作用是什么?
根据上面提到的三点,它是存储库模式的正确实现吗?
这是服务
1 2 3 4 5 | public interface IFoodEstablishmentService { Task<int> AddAsync(FoodEstablishment oFoodEstablishment); Task<int> UpdateAsync(FoodEstablishment oFoodEstablishment); } |
这是我的正常实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | public class FoodEstablishmentService : IFoodEstablishmentService { public async Task<int> AddAsync(FoodEstablishment oFoodEstablishment) { // Insert Operation return result; } public async Task<int> UpdateAsync(FoodEstablishment oFoodEstablishment) { // Update Logic return result; } } |
我就是这样用的
1 2 | IFoodEstablishmentService oFoodEstablishmentService = new FoodEstablishmentService(); oFoodEstablishmentService.AddAsync(oFoodEstablishment); |
但是,如果我可能需要通过队列而不是直接将插入逻辑传递给服务器,等待插入操作完成,然后返回结果,而不是传递队列,然后队列工作人员处理这些操作,该怎么办?所以,我不想把所有的事情都弄乱,而只是用相同的接口实现另一个类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | public class FoodEstablishmentQueueService : IFoodEstablishmentService { public async Task<int> AddAsync(FoodEstablishment oFoodEstablishment) { // Insert Queue Operation return result; } public async Task<int> UpdateAsync(FoodEstablishment oFoodEstablishment) { // Update Queue Logic return result; } } |
这就是我使用它的方式,不打破任何东西是不是很容易,而且正如前面的答案所述,使用DI容器甚至更好地工作
1 2 | IFoodEstablishmentService oFoodEstablishmentService = new FoodEstablishmentQueueService(); oFoodEstablishmentService.AddAsync(oFoodEstablishment); |
我想,不要选择最佳模式,而是先从任何模式开始,然后慢慢地,您将需要更多的东西,然后模式开始发挥作用,另外,存储库模式或通用存储库模式可能不是大型应用程序的理想模式,因为在这些应用程序中,选择逻辑不仅仅是选择模型数据。请搜索CQR模式。
在设计良好的代码中,您必须使用接口,但不能使用实现。它有好处。假设您有一个带有代码片段的类:
1 2 3 4 5 6 | IBookRepository bookRepository; public Book GetInterestingBook() { var book = bookRepository.getBooks().FirstOrDefault(x => x.IsInteresting); return book; } |
现在我将向您展示一些好处:
使用接口可以通过依赖注入(ninject、unity等,其中有很多)隐式地创建BookRepository实例。如果您决定将存储库实现从实体框架更改为nhibernate,则不需要对代码进行更改。只需更改映射文件中的映射即可用于iBookRepository NHibernateRepository而不是eBookRepository。当然,NHibernaterepository也应该得到发展。
使用接口可以通过mockobjects实现伟大的单元测试。您只需要实现mockbookrepository并在注入时使用它。有许多模拟框架可以帮助您使用它,例如moq。
您可以在不更改代码的情况下动态切换存储库。例如,如果您的数据库是临时关闭的,但是您有另一个可以处理新订单的数据库,例如,它们是关键的(我知道,这是个坏例子)。在这种情况下,您会检测到数据库崩溃,并做出如下操作:
CurrentRepository=临时订单或临时报告;
现在,代码继续运行,除了get数据和delete方法返回异常,但createworder()方法将订单保存到字符串文件)
祝你好运!
那个教程很没用。它只是对ef的dbset进行包装。很坏的例子。存储库模式本身意味着您需要根据域需求设计适当的接口。通常至少有3种需求:添加、获取、保存。但一切都取决于你的域名,这一点很重要:没有菜谱,这正是应用程序所需要的。
存储库实现只是对整个业务对象(其中业务对象是业务概念)的持久化/加载。您已经选择了ADO.NET(您应该选择一个微型ORM,因为使用ADO.NET没有任何好处)来与数据库通信。好的,只需保存到数据库,查询数据库例程。
没有关于如何实现存储库的配方/规则。"硬"部分是设计接口。实现只是一个使用DB的类(以任何方式)。
我们使用接口是因为,通常,repo的接口是域的一部分,而它的实现是持久性的一部分。这还允许多个存储库实现,并便于测试(通过模拟)。
顺便说一句,您必须理解存储库模式只是一个简单的原则。它可以以您想要的方式实现,没有"正确"的方式。不过,需要"正确"的是接口设计,即只应使用业务对象,不应泄漏任何实现细节(如iQuery)。