Repository pattern: Limitation, purpose , and benefits - c#

I am new to repository pattern, and I come up the following questions:
What is/are the purpose of repository pattern?
What is/are the limitation of repository pattern?
What is/are the benefits of repository pattern?
Do the methods below should be exposed in the repository pattern?
public IQueryable<T> GetQuery(){
return _objectSet;
}
public IEnumerable<T> GetAll(){
return GetQuery().AsEnumerable();
}
public IEnumerable<T> Find(Expression<Func<T, bool>> predicate){
return _objectSet.Where(predicate);
}
public T Single(Expression<Func<T, bool>> predicate){
return _objectSet.Single(predicate);
}
public T First(Expression<Func<T, bool>> predicate){
return _objectSet.First(predicate);
}
Any help please?

1.What is/are the purpose of repository pattern?
To abstract away the data source to reduce complexity. By doing so the caller do not have to have any knowledge about the data source or it's quirks. They just know that they can invoke the repository and get information from an arbitary data source.
2.What is/are the limitation of repository pattern?
It's only used to abstract away the data source.
A soft limit is that people find it hard to understand how to design the repository classes. It's common that people make the repositories to generic which in turn leaks DB implementation to the invoker, thus forcing the caller to have DB specific knowlegde (or OR/M knowledge). Those implementations are seriously flawed and provide no benefit over using OR/Ms directly.
3.What is/are the benefits of repository pattern?
Less complex code. The caller get's less complex since they only have to invoke a method in the repository to fetch and store information in the data source. And the Data Access Layer get's less complex sinvce the repositories only focuses on retreiving and storing information.
4.Do the methods below should be exposed in the repository pattern?
No. IQueryable<T> leaks DB specific information. You need for instance to know how the OR/M handles translates LINQ to IN SQL clauses and how the OR/M is configured for lazy/eager loading.
To reduce complexity the repository should communicate what kind of queries it support. Using Expression<Func<T, bool>> predicate is like saying throw anything at me and I'll try to handle it. Won't work very well. Again. Take the IN clause as an example. The LINQ statement for it varies between different OR/Ms.
Using expressions also move the responsibility of constructing correct queries to the caller. That means that the unit tests for the caller also have to include tests for validating that the caller makes correct queries. i.e. more complex tests.

Related

how is repository pattern really done?

I'm using elastic search with my asp.net core web api. I don't quite get where the line is drawn when it comes to repository responsibility.
Here is how I have defined my implementations:
public SearchRespository: ISearchRespository<Product>
{
private ElasticClient _client
public async Task<ISearchResponse<Product>> SearchAsync(ISearchRequest request)
{
var response = _client.SearchAsync<Product>(request);
return await products;
}
. . . // others
}
In my controller:
public SearchController : Controller
{
private ISearchRespository _repo;
public SearchController(ISearchRespository repo)
{
_repo = repo;
}
public async Task<IActionResult> Search()
{
// build my search request from Request.Query
var response = await _client.SearchAsync(request);
var model = new SearchModel
{
Products = response.Documents;
Aggregations = response.Aggregations;
}
return Ok(model)
}
As it stands the repo is passing the elastic response as is. My question is have I drawn my line right? what if I just move _client to my controller or move building request and constructing model to _repo? how do you guys get your repository right?
The fact that you use Elastic Search should be an implementation detail that especially the controller shouldn't know about, so you are absolutely right in abstracting this away from the controller. I often look at the SOLID principles to get a sense whether I'm on the right track or not. If we look at the Dependency Inversion Principle, you'll see that it guides us towards a style that is also known as Ports and Adapters, which basically means that the use of an external tool is abstracted away (the port), and on the boundary of the application you implement an Adapter that connects to that third party.
So from the sense of the Dependency Inversion Principle, you're on the right track.
There is however a lot of misunderstanding of what Martin Fowler's Repository Pattern is trying to solve. The definition is as follows:
Mediates between the domain and data mapping layers using a collection-like interface for accessing domain objects.
Important to note here is that a repository is intended to be used by the domain layer.
There is however a lot of misuse of the repository pattern, because many developers start to use it as a grouping structure for queries. The repository is -as I see it- not intended for all queries in the system; but only for queries that are the domain needs. These queries support the domain in making decisions for the mutations on the system.
Most queries that your system requires however are not this kind of query. Your code is a good example, since in this case you skip the domain completely and only do a read operation.
This is something that is not suited for the repository. We can verify this by comparing it with the SOLID principles again.
Let's say we have the following repository interface:
public interface IUserRepository
{
User[] FindUsersBySearchText(string searchText, bool includeInactiveUsers);
User[] GetUsersByRoles(string[] roles);
UserInfo[] GetHighUsageUsers(int reqsPerDayThreshold);
// More methods here
}
This is a typical repository abstraction that you'll see developers write. Such abstraction is problematic from perspective of the SOLID principles, because:
The Interface Segregation Principle is violated, because the interfaces are wide (have many methods) and consumers of those interfaces are forced to depend on methods that they don’t use.
The Single Responsibility Principle is violated, because the methods in the repository implementation are not highly cohesive. The only thing that relates those methods is the fact that they belong to the same concept or entity.
The design violates the Open/Closed Principle, because almost every time a query is added to the system, an existing interface and its implementations need to be changed. Every interface has at least two implementations: one real implementation and one test implementation.
A design like this also causes a lot of pain down the road, because it becomes hard to apply cross-cutting concerns (like security, auditing, logging, caching, etc) down the line.
So this is not something the Repository pattern is intended to solve; such design is just a big SOLID violation.
The solution here is to model queries separately in your system and not use a repository at all. There are many articles written about this, and you can read my take on this here.
If I look at your design, it actually has some resemblance with the design I'm promoting here, since you seem to have a generic query method that can handle many type of queries. The query message (your ISearchRequest) seems however specific to Elastic Search. This is something you should strive to prevent, as the Dependency Inversion Principle states.

Dbcontext class simple interpretation

would anybody interpret it into simple words as i'm newbie to MVC and can't understand this clearly.
A DbContext instance represents a combination of the Unit Of Work and
Repository patterns such that it can be used to query from a database
and group together changes that will then be written back to the store
as a unit. DbContext is conceptually similar to ObjectContext.
Source: http://msdn.microsoft.com/en-us/library/system.data.entity.dbcontext(v=vs.113).aspx
Unit of work and Repository are patterns for dealing with data(irrespective of if it is a database or any other storage(may be List<T> objects even)) and usually implemented while dealing with data from a database.
It only means that Entity framework internally has these two patterns implemented. To understand it better, just google for Repository Patterns and Unit of work pattern which usually go hand in hand.
If you still do not get the meaning, don't worry - until you know how to work with Entity Framework(Code First is extremely easy to understand, once you understand Linq) the understanding of pattern is not important. Refer back to the same article once you have more experience with the patterns of dealing with data. You only require a little more experience to appreciate them.
Examples of these two patterns are better described by the two interfaces:
interface IHomesRepository {
List<Home> GetAllHomes();
Home GetHomeById(int id);
void AddHome(Home home);
void UpdateHome(int id, Home home);
void DeleteHome(Home home);
}
interface IUnitOfWork : IDisposable{
IHomesRepository repository {get;}
// more repositories, if required
void Commit();
}
this is a good example to understand the unit of work and the repository pattern, i suggest you to read it until the end :
http://www.asp.net/mvc/tutorials/getting-started-with-ef-5-using-mvc-4/implementing-the-repository-and-unit-of-work-patterns-in-an-asp-net-mvc-application

One big repository vs. many little ones?

I have several product tables in my database:
ProductTypes
ProductCategories
ProductCategoryItems
ProductInventory
The way I see it now, I can make IProduct which would have methods such as:
FindAllTypes()
FindAllCategories(int typeId)
FindAllItems(int categoryId)
Or, I can separate each to mimic the table structure: IProductType, IProductCategory, etc.
Is there a reason to go with one over another?
The idea of repositories is to delegate each one with responsibility for a single entity. In this case making a repository for each entity is recommended. You can go for the big repository one as well, but is not the best solution. In the end you'll get a HUGE class with lots of methods and really tight coupled. Also difficult to give maintenance to.
I don't think having a huge repository is really a good idea, then you'd basically have a data access god class that does everything.
I like to have a base Repository<T> which does common operations such as GetById and GetAll. I normally have all my repositories inherit this base class to get the common methods for free, so I don't have to keep rewriting the same code.
In my opinion it very much depends on the business domain model, it's very important to determine what are your main business entities. Not necessarily every table in the DB is directly mapped to a business entity. Tables are just representations of your one or many entities in a normalized way for relational databases.
Try to picture your domain model beyond the restrictions of normalized relational databases, is there really more than one business concept? Repositories should be constructed around solid, whole, first-class business entities.
My advice would be to have an IProductRepository with the necessary methods to implement CRUD operations and grow it as needed. You don't want to get too ambitious interfaces beacuse you may not need most of it, and it could be a burden. The important thing about interfaces is to decouple your code from the persistence schema, so you can latter offer the flexibility to switch between them.
Maybe in the future the business will need to evolve to a more detailed representation of -for instance- the product's providers, and in that moment you'll use your good judgement to decide wether that represents an important business entity worthy of a dedicated repository or not.
Hope this helps.
I disagree with the others (edit: except with Isaac). The small repositories are a facade (not the pattern).
If the entity types are coupled (have navigation properties to each other) then they are not really separatable.
Modifying one entity type and committing the changes may commit change to others.
Also, you can not create any small repository above the same unit of work,
since the ORM only has a limited amount of entities mapped to the database.
Divide your model into separatable domains and create one specific unit of work for each domain.
On these unit of works create aggregate roots for each entity type that you may require immediate access to.
Each root should have specifically typed add, remove, getbykeys, query and etc methods.
The unit of work should have the commitchanges and alike methods on it.
Each of the roots is similar to the small repositories the others mentioned, however, the unit of work is the real medium sized repository (of which your model may have more than one type of).
Example:
// Create one of these
interface IUnitOfWork
{
void Commit();
}
// Create one of these
interface IEntitySet<TEntity> where TEntity : class
{
void Add(TEntity entity);
void Remove(TEntity entity);
TEntity Create<TSpecificEntity>() where TSpecificEntity : TEntity;
IQueryable<TEntity> Query();
}
// Create one of these per entity type
interace IEntitySetOfTEntity1 : IEntitySet<Entity1>
{
TEntity1 GetByKeys(int key1);
}
interace IEntitySetOfTEntity2 : IEntitySet<Entity2>
{
TEntity1 GetByKeys(short key1, short key2);
}
// Create one of these per separatable domain
interface IDomain1UnitOfWork : IUnitOfWork
{
IEntitySetOfTEntity1 Entity1s
{
get;
}
IEntitySetOfTEntity2 Entity2s
{
get;
}
}
All these interfaces and their implementations can be auto-generated.
These interfaces and their implementations are very light weight and by no means are any of them "a HUGE class with lots of methods". Since they can be auto-generated, maintenance is easy.
Specific functionalities can be added to the interfaces IDomain1UnitOfWork, IEntitySetOfTEntity1 and alike by using:
a. extension methods
b. partial interfaces and classes (less recommended, since this results in a less clean DAL)
The IEntitySetOfTEntity1 like interfaces can be disgarded if you use extension methods to add the GetByKeys() methods to IEntitySet<Entity1>.

Advice With Repository/Service Layer Design Pattern

Trying to make a really simple repository and service layer pattern here. (.NET 4, C#, LINQ, although this question is partially language-agnostic). Note: this is just R&D.
My goal is to minimize the amount of method definitions in my service layer.
Here's my Repository Contract:
interface IFooRepository
{
IEnumerable<Foo> Find();
void Insert(Foo foo);
void Update(Foo foo);
void Delete(Foo foo);
}
Nothing new there.
Now, here's what im (trying) to have in my Service Contract:
interface IFooDataService
{
public IEnumerable<Foo> Find(FooSearchArgs searchArgs);
}
Essentially, any particular "Foo" has many properties (id, name, etc), which i would like to be able to search upon.
So, i dont want to have 1x Find method for each different property, i just want one - that way when i create extra properties i dont have to modify the contracts.
The "FooSearchArgs" is just a simple POCO with all the different "Foo" properties it.
So, that's what im trying to do, here's my questions:
Is this poor design? If so, what are the alternatives?
How can i implement this filtering in the service layer? Would i have to check what properties of "FooSearchArgs" are set, then keep filtering down? (if this, then query.where, if this, query.where, etc) Anyone have an idea of a clever LINQ IEnumerable extension method to do this? (ie repository.WhereMeetsSearchCriteria(fooSearchArgs))
Appreciate the help.
We use something very similar. One thing you need to decide on is if you are going to expose IQueryable outside of the repository. Your find method returns IEnumerable which could be the IQueryable returned from your when clause.
The advantage of returning the IQueryable is that you can further refine your criteria up outside of your repository layer.
repository.Find(predicate).Where(x => x.SomeValue == 1);
The expression will only be compiled when you come to use the returned data and here in lies the disadvantage. Because you only hit the database when you actually come to use the results you could end up trying to call the database after your session (nhibernate) or connections have been closed.
My personal preference is to use the specification pattern where you pass your find method an ISpecification object is used to do the query.
public interface ISpecification<TCandidate>
{
IQueryable<TCandidate> GetSatisfyingElements(IQueryable<TCandidate> source);
}
public class TestSpecification : ISpecification<TestEntity>
{
public IQueryable<TestEntity> GetSatisfyingElements(IQueryable<TestEntity> source)
{
return source.Where(x => x.SomeValue == 2);
}
}
public class ActiveRecordFooRepository: IFooRepository
{
...
public IEnumerable<TEntity> Find<TEntity>(ISpecification<TEntity> specification) where TEntity : class
{
...
return specification.GetSatisfyingElements(ActiveRecordLinq.AsQueryable<TEntity>()).ToArray();
...
}
public TEntity FindFirst<TEntity>(ISpecification<TEntity> specification) where TEntity : class
{
return specification.GetSatisfyingElements(ActiveRecordLinq.AsQueryable<TEntity>()).First();
}
}
After the query is run the repository calls ToArray or ToList on the resulting IQueryable returned from the specification so that the query is evaluated there and then. Whilst this may seem less flexible than exposing IQueryable it comes with several advantages.
Queries are executed straight away and prevents a call to the database being made after sessions have closed.
Because your queries are now bundled into specifications they are unit testable.
Specifications are reusable meaning you don't have code duplication when trying to run similar queries and any bugs in the queries only need to be fixed in one place.
With the right kind of implementation you can also chain your specifications together.
repository.Find(
firstSpecification
.And(secondSpecification)
.Or(thirdSpecification)
.OrderBy(orderBySpecification));
Is passing a Func as a parameter to your service layer's Find method, instead of the FooSearchArgs, an option? Enumerables have a Where method (linq) that takes a Func as a parameter, so you could use it to filter the results.

Patterns for using EntityFramework?

What is alternative patterns of using for Entity Framework ?
Some I know are:
"Plain" EntityFramework - aka Unity of Work
using (Data.Model c = new Data.Model())
{
var z = c.Users.Where(x=>x.Name=='John');
}
Repository pattern
//Model implements IRepository
User user = Model.Instance.Get<User>(u => u.Name == "John");
What else ?
?
A good book to look at is Martin Fowler's "Patterns of enterprise application architecture".
There he goes through some patterns for retrieving/mapping data like DTOs, Unit of work, repository pattern etc... Maybe something could be useful together with the Entity Framework. I'd have to take a look at it.
I answer your question based on the assumption that you are using Entity Framework directly in your UI/controller/Services.
It has been proven that using any ORM, inclusing EF, directly in your UI/Controllers/Services will cause a lot of problem in the future. On top of that, it makes it so hard, if not impossible, to unit test your application.
The second approach ie "Model implements repository" is also wrong in my opinion, becuase Model and Respositories have different responsiblities and based on "Single Responsibilty" part of SOLID principles you should not merge the two concepts together. Even if you want to use Active Objects pattern in your model, which I don't recommend, you must decouple your model from the ORM you use.
The best and the most recommended solution is to have an interface like IRepository or IRepository with the very basic members as the pattern suggests. something like:
Interface IRepository<T> where T:class
{
void Insert(T entity);
void Update(T entity);
void Delete(T entity);
// if you don't want to return IQueryable
T FindById(object id);
IEnumerable FindXXXXX(params)
// if you prefer to return an IQueryable
IQueryable<T> Find(Expression<Func<T, bool>> predeicate);
}
Note that some poeple beleive Repositories should not return IQueryable. Additionally, You can consider using ISpecification instead of expressions and lambda.
you would need to implement IRepositoy interface for most of your entities. Using this approach you can also mock your repositories when writing unit tests. In production, you would need to use an Ioc provider such as Unity, Ninject, Linfu, Catsle and etc. you can also benefit from microsoft's common service locator implementation to avoid coupling to a specifi IoC framework.
In the old days, I used to have a data access interface which was impleneted for a specific business domain or a service. One of the issues with this approach is that you would end up with duplicate code in different data access services if you keep track of your source code and you will eventually.
We use code similar to what you have in your unit of work example.
What we do in addition is to map objects to Data Transfer Objects.
There are many articles on the subject, but the list will be reduced substantially if you'd like a good one. This article from MSDN Magazine is pretty good, although it deals specifically with n-tier applications. But since you don't say what you're building, maybe it will help.
LINQ 2 SQL can be an alternative. Here is an article Dependency Injection with Unity and Linq to SQL DataContexts
UNITY - http://unity.codeplex.com/

Categories