When to use Repository pattern in application?

A software design pattern is a general reusable solution to a common occurring problem within a context in software design. In this post, I’ll tell you when to use Repository pattern in application. With correct understanding of the concepts, this knowledge can also be applied to a ASP.NET MVC or Web API application. I’ll use ASP.NET MVC web application to explain examples in this post.

Repository Pattern

Mediates between the domain and data mapping layers using a collection-like interface for accessing domain objects.
– P of EAA – Martin Fowler

This pattern can basically reduce duplicate query logics for your application and thus, provides better separation of concerns (SoC). The controllers of your web application should not handle the data query logics instead it can rely on some other entity to provide data on demand.

Not every size of application needs this pattern. A good question is when to use this pattern or identify the need of introducing such a pattern in your application. Look for following cases:

When your application has complex queries in use at different places. Also, just having private methods to make these queries may solve this problem for a while but still this situation can be avoided.

The intermediate layer in your web application i.e. controllers can easily get fat. The only job of controller is to handle web requests and execute it properly without having additional responsibility like handling complex query logics.

Like fat controllers, you may have fat services, so watch out for this too.

Example

Let us take an example that illustrates the before and after code just to illustrate how using repository pattern can help us writing clean code. Below is an Events controller class that uses a custom DbContext class to query events and associated artist, genre, etc. information.

As you can see the highlighted code below is querying logic that actually is not this controller’s responsibility. It adds too much detail to the action’s implementation. Also, I’ve got another controller that needs similar query logic for Events, so one way is to extract a private method or the better way is to work on Repository class to handle these complex queries.

Example of controller with complex query logic

C#

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

publicclassEventsController:Controller

{

privatereadonlyApplicationDbContext _context;

publicEventsController()

{

_context=newApplicationDbContext();

}

publicActionResult Details(intid)

{

varevent=_context.Events

.Include(g=>g.Artist)

.Include(g=>g.Genre)

.SingleOrDefault(g=>g.Id==id);

if(event==null)

returnHttpNotFound();

varviewModel=newEventDetailsViewModel{Event=event};

returnView("Details",viewModel);

}

[Authorize]

publicActionResult MyEvents()

{

varuserId=User.Identity.GetUserId();

varevents=_context.Events

.Where(g=>

g.ArtistId==userId&&

g.DateTime>DateTime.Now&&

!g.IsCanceled)

.Include(g=>g.Genre)

.ToList();

returnView(events);

}

}

Next, the controller that uses Repository class to achieve the same purpose as above:

Example of controller using a repository

C#

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

publicclassEventsController:Controller

{

privatereadonlyApplicationDbContext _context;

privatereadonlyEventRepository _eventRepository;

publicEventsController()

{

_context=newApplicationDbContext();

_eventRepository=newEventRepository(_context);

}

publicActionResult Details(intid)

{

varevent=_eventRepository.GetEvent(id);

if(event==null)

returnHttpNotFound();

varviewModel=newEventDetailsViewModel{Event=event};

returnView("Details",viewModel);

}

[Authorize]

publicActionResult MyEvents()

{

varuserId=User.Identity.GetUserId();

varevents=_eventRepository.GetUpcomingEventsByArtist(userId);

returnView(events);

}

}

As you can see in the highlighted code above, controller now uses a EventRepository and controller doesn’t need to deal with any extra responsibility of complex data query logic. An application may have more than one repository for each data entity that exists in the application.

Also, a reader reading this controller code doesn’t need to know the detail of how event or upcoming events by artist is fetched and the code is clean enough to understand easily. Let’s look at the definition of repository now:

Event Repository class definition

C#

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

publicclassEventRepository

{

privatereadonlyApplicationDbContext _context;

publicEventRepository(ApplicationDbContext context)

{

_context=context;

}

publicEventGetEvent(inteventId)

{

return_context.Events

.Include(g=>g.Artist)

.Include(g=>g.Genre)

.SingleOrDefault(g=>g.Id==eventId);

}

publicIEnumerable<Event>GetUpcomingEventsByArtist(stringartistId)

{

return_context.Events

.Where(g=>

g.ArtistId==artistId&&

g.DateTime>DateTime.Now&&

!g.IsCanceled)

.Include(g=>g.Genre)

.ToList();

}

}

Now, if you think that this controller has extra responsibility to create this repository as well as DbContext then it really depends on the needs of the application. This can be resolved using Inversion of Control (IoC) concept. Anyway, not all applications needs Dependency Injection (DI) but it is good idea to have this in a medium or large size application. I’ll write another post for this soon. For updates, please subscribe to my blog.

Siddharth Pandey is a Software Engineer with thorough hands-on commercial experience & exposure to building enterprise applications using Agile methodologies. Siddharth specializes in building, managing on-premise, cloud based real-time standard, single page web applications (SPAs). He has successfully delivered applications in health-care, finance, insurance, e-commerce sectors for major brands in the UK. Other than programming, he also has experience of managing teams, trainer, actively contributing to the IT community by sharing his knowledge using Stack Overflow, personal website & video tutorials.