AspNetCore.Docs/aspnetcore/fundamentals/repository-pattern.md

6.0 KiB

title author description ms.author ms.custom ms.date uid
Repository pattern with ASP.NET Core ardalis Learn how to implement the repository app design pattern in an ASP.NET Core app. riande mvc 07/02/2018 fundamentals/repository-pattern

Repository pattern with ASP.NET Core

By Steve Smith, Scott Addie, and Luke Latham

The repository pattern is a design pattern that isolates data access behind interface abstractions. Connecting to the database and manipulating data storage objects is performed through methods provided by the interface's implementation. Consequently, there's no need for calling code to deal with database concerns, such as connections, commands, and readers.

Implementation of the repository pattern with ASP.NET Core has the following benefits:

  • Organization of the app is less complex with no direct interdependency between the business and data access layers.
  • It's easier to reuse database access code because the code is centrally managed by one or more repositories.
  • The business domain can be independently unit tested from the database layer.

View or download sample code (how to download)

The sample app uses the repository pattern to initialize and display a list of movie character names. The app uses Entity Framework Core and an ApplicationDbContext class for its data persistence, but the database infrastructure isn't apparent where the data is accessed. Data access and database objects are abstracted behind a repository.

Repository interface

A repository interface defines the properties and methods for implementation. In the sample app, the repository interface for movie character data is ICharacterRepository. ICharacterRepository defines the ListAll and Add methods required to work with Character instances in the app:

::: moniker range=">= aspnetcore-2.1"

[!code-csharp]

::: moniker-end

::: moniker range="= aspnetcore-2.0"

[!code-csharp]

::: moniker-end

Character is defined as:

::: moniker range=">= aspnetcore-2.1"

[!code-csharp]

::: moniker-end

::: moniker range="= aspnetcore-2.0"

[!code-csharp]

::: moniker-end

Repository concrete type

The interface is implemented by a concrete type. In the sample app, CharacterRepository manages the database context and implements the ListAll and Add methods:

::: moniker range=">= aspnetcore-2.1"

[!code-csharp]

::: moniker-end

::: moniker range="= aspnetcore-2.0"

[!code-csharp]

::: moniker-end

Register the repository service

The repository and database context are registered with the service container in Startup.ConfigureServices. In the sample app, ApplicationDbContext is configured with the call to the extension method AddDbContext. ICharacterRepository is registered as a scoped service:

::: moniker range=">= aspnetcore-2.1"

[!code-csharp]

::: moniker-end

::: moniker range="= aspnetcore-2.0"

[!code-csharp]

::: moniker-end

Inject an instance of the repository

In a class where database access is required, an instance of the repository is requested via the constructor and assigned to a private field for use by class methods. In the sample app, ICharacterRepository is used to:

  • Populate the database if no characters exist.
  • Obtain a list of the characters for display.

Notice how the calling code only interacts with the interface's implementation, CharacterRepository. Calling code doesn't use the ApplicationDbContext directly:

::: moniker range=">= aspnetcore-2.1"

[!code-csharp]

::: moniker-end

::: moniker range="= aspnetcore-2.0"

[!code-csharp]

::: moniker-end

Generic repository interface

This topic and its sample app demonstrate the simplest implementation of the repository pattern, where one repository is created for each business object. If the app grows beyond a few objects, a generic repository interface may reduce the amount of code required to implement the repository pattern. For more information, see DevIQ: Repository Pattern: Generic Repository Interface.

Additional resources