了解存储库模式

时间:2013-11-26 06:28:16

标签: repository-pattern

存储库模式易于实现,但我遇到了一个小问题。如果有人认为我的代码很长,我很抱歉,但是当我理解时,这对我来说非常值得。

我创建了一个简单的界面,如下所示: -

public interface IBookRepository
{
    List<Books> GetUsers();
    void Save();
}

以下是实现IBookRepository接口的类

public class BookRepository : IBookRepository
{
    private PosContext context;

    public BookRepository(PosContext context)
    {
        this.context = context;
    }

    public List<Books> GetUsers()
    {
        return context.Book.ToList();
    }
}

以下是BookController: -

public class BookController : Controller
{
    #region Private member variables...
    private IBookRepository bookRepository;
    #endregion

    public BookController()
    {
        bookRepository = new BookRepository(new PosContext());
    }

    public ActionResult Index()
    {
        var query = (from c in bookRepository.GetUsers()
                     select c).ToList();

        //var userList = from user in userRepository.GetUsers() select user;
        var users = new List<Books>().ToList();

        ViewBag.Message = "Modify this template to jump-start your ASP.NET MVC application.";

        return View(users);
    }
}

感谢您阅读以上代码: - 现在我的问题出现在以下代码行

private IBookRepository bookRepository;
public BookController()
{
    bookRepository = new BookRepository(new PosContext());
}

在第一行的上面代码中我们写bookRepository基本上是IBookRepository接口的引用(正如我在某处读到的那样)。为什么我们在这里使用它?如果我直接编写以下代码行,它也可以很好地工作。

private BookRepository bookRepository;
public BookController()
{
    bookRepository = new BookRepository(new PosContext());
}

请注意在第二个最后一个代码快照我使用IBookRepository并在最后一个代码shapshort我只使用BookRepository我不明白上面两个代码的区别没有错误,如果有人请澄清我的理解我会非常感激并且感恩。

感谢。

1 个答案:

答案 0 :(得分:0)

你注意到的是正确的。当你像这样构造它时没有多大用处。您可以像下面这样进行演变:

private IBookRepository _bookRepository;
public BookController(IBookRepository bookRepository)
{
    _bookRepository = bookRepository;
}

这里,自然的问题是“谁将bookRepository传递给构造函数?”。在.NET中,我们可以使用Ninject,Unity等依赖注入框架来完成它。

Dependecy Injection框架基本上使您能够将接口映射到具体类,因此当运行时查找IBookRepository时,将返回new BookRepository()的实例。

你可能会问有什么好处。答案是单元测试。然后,您可以执行如下所示的单元测试。通过使我们的控制器依赖于IBookRepository而不是BookRepository,我们可以实现单元测试。现在请注意,我们可以传递任何像FakeBookRepository这样的IBookRepository进行单元测试。

[Test]
public void Index_Passes_Correct_Model_To_View()
{
  //Arrange
  IBookRepository bookRepository = new FakeBookRepository();
  var controller = new BookController(bookRepository);

  //Act
  var result = (ViewResult) controller.Index();

  // Assert
  var listBooks = result.ViewData.Model;
  Assert.Equal(1, listBooks.Count());
}

,其中

public class FakeBookRepository : IBookRepository
{
   public List<Books> GetUsers()
   {
       return new List<Book> { new Book() { Id=1 , Name = "abc" } };
   }
}