Specification pattern with Entity Framework generic repository pattern - c#

Recently I have encountered an article Implement the Query Specification pattern and I am confused about using specification pattern with generic repository.
I have already a generic repo like this:
public interface IGenericRepository<T> where T:class
{
IReadOnlyList<T> GetAllAsunc(int id);
IReadOnlyList<T> FindAsync(Expression<Func<T, bool>> filter);
T GetById(int id)
void Add(T item);
void Update(T item);
void Delete(T item);
}
And a sample method for specification pattern
public BaseSpecification(Expression<Func<T, bool>> criteria)
{
Criteria = criteria;
}
I can send any expression with IReadOnlyList<T> FindAsync(Expression<Func<T, bool>> filter); method. So, I don't really understand why I need specification pattern with generic repository. It looks they are doing same things. Could you clarify this?

The specification pattern covers more than just a filter expression, it also covers eager loading and pagination. In your example, if you were dealing with an entity that referenced 3 other entities and had a child collection, how would you tell your repository method which of those should be eager loaded? If your List method could return hundreds of thousands of rows, how would you tell it to load just a page of 50 at a time?
In my personal opinion, using the Specification is a SRP band-aid on a generic repository. Generic repositories are an anti-pattern in EF systems where you are positioning your repository code to have a great number of "forces" lobbying for change using the Specification to mitigate that. I would never advocate for trying to build an MVC web application with a single generic Controller<T> implementation, and for the same reason I don't advocate using Repository<T>.
Specifications do not protect callers from being polluted with domain / EF knowledge because every expression passed in must conform to the rules set out by the domain implementation. While a specification might handle filtering, eager loading, and pagination... What about sorting, projection, or other aggregate functions like exist checks and counts? At the end of the day it's a complexity rabbit hole trying to satisfy S.O.L.I.D. principles making your code considerably more complex and harder to follow, and slamming head-first into barriers repeatedly as new requirements don't conform to past assumptions.

Related

Use repository without Entity Framework

I try to figure out how to implement the repository pattern WITHOUT Entity Framework. I need to use the ADO.NET(disconnected) implementation,(withot DbContext). I know if it is possible.
I have one interface of Repository like it:
public interface IRepository<T>
{
void Add(T newEntity);
void Remove(T Entity);
void Update(T Entity);
IQueryable<T> GetAll();
T Get(object key);
void SaveChanges();
}
So, I just need to know how use it with ADO.NET connection and Mapper or other thing.
Your question is about the repository pattern, however your sample looks more like writing a custom linq provider.
This is actually rather complex thing, and what i think you actually need is to really use the repository pattern, where you have methods like GetCar(int Id) that you then implement specifically using what ever framwork you want.
The diffrence is that with a linq provider like EF, you're exposing the ability for callers to write write any query they want. However, technically this breaks the repository pattern. The idea with the Repo pattern is to contain all the queries in a single class that then expose methods for doing only what the application needs. This way you don't get queries all over your code, and you can implement only the operations your application needs.
In other words, EF is not really an example of the repository pattern, it's a way to talk to the database and create classes that represent the entities in the database. Typically you'd use EF or something similar inside your repository and possibly expose the actual entity types for the outside to use.
Now, writing a custom linq provider is still interesting and if you want to do it, check out this series:
http://www.jacopretorius.net/2010/01/implementing-a-custom-linq-provider.html

How can I decouple the EF POCO from the generic IRepository in this pattern?

I currently have a Repository/UnitOfWork pattern down. However, there is one hard coupling that I am unable to figure out how I can get rid of.
This is an overview of my pattern:
Business Logic Layer
IRepository
Used as type contraint
IRepository< TModel, TDTO >
Implements IRepository
General CRUD methods
IEmployeeRepository< TModel >
Implements IRepository< TModel, EmployeeDTO >
Some employee specific methods
IUnitOfWork
Getter for repositories
Save method
IEntityWithId
Interface to force (and expose) DTOs and EF POCOs to have a Int32 field called ID
Used as type contraints
EmployeeDTO (Mapped with AutoMapper in the implemented EmployeeRepository)
DTO entity used in the core project and (to come) test project
Data Layer (Injected with Ninject)
UnitOfWork
Implementation of IUnitOfWork based on Entity Framework
EmployeesRepository
Implementation of IEmployeeRepository< TModel >
Employee
EF POCO
Core
EmployeesController
Parametered constructer EmployeesController(IUnitOfWork unitOfWork)
IUnitOfWork is injected with a Ninject module as a UnitOfWork (from Data layer)
Those are the problem methods in my generic IRepository interface.
TDTO Find(Expression<Func<TModel, bool>> filter);
and
IEnumerable<TDTO> FindAll(Expression<Func<TModel, bool>> filter);
As you can see, there is TModel in there, which is used to build up an expression to filter results. I COULD do something like using an expression on the DTO, but that would require a complete list of employees mapped to DTOs (aka it wouldnt generate a SQL filter but it would filter a SELECT * FROM Employee result list). So this isn't a good option.
The other, more viable but not optimal solution is to use dynamic LINQ. That way, I can pass a simple string in the Find / FindAll methods and get rid of the TModel requirement. However, this would means that refactoring becomes annoying since it fills the code with magic strings.
Just as I posted this, I think I figured out where my problem is.
Find() and FindAll() shouldn't even exist. I should write more specific methods like FindEmployeeByName(string name) in the IEmployeeRepository, then implement it like so :
EmployeeDTO FindEmployeeByName(string name)
{
return Mapper.Map<EmployeeDTO>(dbSet.Where(o=>o.name.Contains(name)).FirstOfDefault());
}
Can anyone confirm this is a proper way to do it? Or suggest something even better?
Edit
Also, if I want to keep Find(Expression...) and FindAll(Expression...) methods, I can, but they are just in the Data layer and used by implemented methods to avoid repeated code. But they should not be used in controllers as they requires knowledge of the underlaying data structure, beyond my Business Logic. That said, they can be implemented in a BaseRepository< TModel > (That I already have but did not mention to keep things more simple) and make EmployeesRepository an extention of BaseRepository. That way, every Repository already have those generic-like method that are Model-Aware.
Not sure if I explained that properly. Let me know if it's unclear and I'll try to edit this and make it better.
Another way to do this is to make your data layer depend on the business layer and have your repository "project" entities into your business objects (DTO's). This way your BL is at the bottom and UI and Data depend on it, but UI and Data do not depend on each other.
This is the method espoused by Mark Seemann in his book on Dependency Injection.

Is there a suggested pattern for using LINQ between the Model & DataAccess Layers in a DDD based Layered Architecture

I've been reading Tim McCarthy's awesome book on DDD in .NET. In his example application though, his underlying data access is using SqlCE and he's handcrafting the SQL inline.
I've been playing with some patterns for leveraging Entity Framework but I've gotten stuck on how exactly to map the IRepository linq queries to the underlying data access layer.
I have a concrete repository implementation called.
public EFCustomerRepository : IRepository<DomainEntities.Customer>
{
IEnumerable<DomainEntities.Customer> GetAll(
Expression<Func<DomainEntities.Customer, bool>> predicate)
{
//Code to access the EF Datacontext goes here...
}
}
In my EF Model, I'm using POCO Entities but even so there's going to be no native mapping between my DomainEntity.Customer & my DataAccessLayer.Customer objects.
so I can't just pass Expression<Func<DomainEntities.Customer, bool>> predicate as the parameter for an EFContext.Customers.Where(...);
Is there an easy way to map an
Expression<Func<T, bool>> predicate => Expression<Func<TOTHER, bool>> predicate
Or am I going about this all wrong ?
Any suggestions / pointers appreciated.
In such case you must implement your own custom convertor of one expression tree to another one (probably more then one) which will fully involve your mapping logic. Generally your expression is at the moment just specification (specification pattern) and you must transform that specification to store expression.
Btw. it is wrong. There should not be separate data access layer objects - data access layer should load and save your domain objects directly but EF is not fully capable to do it correctly because its mapping functionality is limited and it pushes its own requirements to entities. You should check NHibernate or other ORM if you want to do DDD seriously (by book).
From the code provided in your example I guess you are not using a generic repository pattern?
I use EF CodeFirst (but it works for old EF to) with a generic repository pattern... http://average-uffe.blogspot.com/2011/03/repository-pattern-with-ef-code-first.html
I do not have the Expression<Func<DomainEntities.Customer, bool>>
in that post, but I always have a Find metod in the IRepository<T> interface.
The interface:
IEnumerable<T> Find(Expression<Func<T, bool>> expression, int maxHits = 100);
And the implementation in the abstract baserepository:
public virtual IEnumerable<T> Find(Expression<Func<T, bool>> expression, int maxHits = 100) {
return this.DataContext.DbSet<T>().Where(expression).Take(maxHits);
}
And now you can call Find on any entity by a lambda expression...
I can post a full example if you do not get it right, just say when.

Create repository without using IQueryable for specification

I've recently been looking into DDD, repositories and the specification pattern and after reading a hand full of blogs and examples I'm trying to come up with a repository that I'm happy with.
I have been exposing IQueryable on my repositories until recently but after understanding that IQueryable is a leaky abstraction because of it is deferred execution and is effectively crossing the boundry from my data layer I have changed it so that my repositories return IEnumerable instead.
So I might have something like this for example:
public interface IUserRepository
{
IEnumerable<User> All();
void Save(User item);
void Delete(User item);
}
I thought okay that seems good but what if I wanted to filter the data my firstname or email? After reading a blog post I implemented a way of passing ICriteria into the All() method.
public IEnumerable<TEntity> All(ICriteria<TEntity> criteria)
{
return criteria.BuildQueryFrom(Set).ToList();
// Set is a DbSet from EntityFramework
}
And an example criteria class:
public class AccountById : ICriteria<Account>
{
private readonly int _id;
public AccountById(int id)
{
_id = id;
}
IQueryable<Account> ICriteria<Account>.BuildQueryFrom(DbSet<Account> dbSet)
{
return from entity in dbSet
where entity.Id == _id
select entity;
}
}
This works fine and I can build these criteria classes to meet my requirements and pass them into the repos and all works well.
One thing I don't like though is being tied to IQueryable because I have to use an ORM that supports Linq so if I wanted to use SqlCommand in my repository for say performance sake or so I can write cleaner SQL rather than the ORM generated SQL, how would I go about doing that?
I would also like to avoid having to write a new method for each filter like FindById, FindByUsername, FindByEmail etc.
How would I go about creating a repository that allows me to specifiy the criteria I want to select without using IQueryable so it would still work whether I used EF, nHibernate or just plain SqlCommand? I'm stuggling to find an example that uses SqlCommand and the specification pattern.
How did people used to do it before ORMs?
Personally, I don't mind IQueryable being a leaky abstraction, because it allows me to write LINQ queries in my service layer and and therefore have more testable code. As long as objects that implement IQueryable are kept inside the service layer (i.e. don't return them to the presentation layer) I don't see a problem. It maximizes the testability of your application. See for instance my blog post about testable LINQified repositories.

Repository Pattern: How to implement a basic Repository including a predicate in C#?

I am new to repositories. I just read about implementing predicates and a Unit of Work (Fowler). I have seen repository interfaces like the following:
public interface IRepository<ET> {
ET Add( ET entity);
ET Remove( int id);
ET Get( int id);
IList<ET> Get(Expression<Func<T, bool>> predicate);
}
Of course the Unit of Work would inject a data context (Microsoft fan) to the new repository, where the Unit of Work would have a .Save() method, calling Save on all data contexts.
There's no Edit method, so I assume you can modify any Entity that pops out of the Repository then call save changes on the Unit of Work.
Is this correct? Leaky? What am I missing? Do methods of OrderBy need not ever be in a Repository? Should Paging (.Skip().Take()) somehow be implemented in the predicate?
Links to example code out there would be fantastic, especially how to implement the predicate in a repository.
if you are referring Entity Framework
i would you suggest you read this: Link
Update:
I am not a expert in repository pattern, however i do using it in my project now. a part form performance, following is the benefits that i find from this design pattern:
1, Simplify CRUD operation implementations for all entities.
with one interface:
public interface IDataRepository<T> where T : class
then you will be able to replicate others very easily and fast
public class EntityOneRepository : IDataRepository<EntityOne>
public class EntityTwoRepository : IDataRepository<EntityTwo>
2, Keeps my code dry.
some entities may have their own method for data manipulation. (i.e. store procedure)
you can extend it easily without touching other repositories.
public interface IDonationRepository : IDataRepository<Donation>
{
//method one
//method two
//....
}
for the Paging, it can be either done by Skip() and take(), or you can define your own SP in database then call it via EF4. in that case you will benefit from database sp caching as well.
Some time, keeping the code clean and logically readable is also important for a better app structure.
The repository interface you've presented is a very easy-to-use CRUD interface that can work well in many types of applications. In general, I'd rather not have paging and sorting parameters or options on my repository, instead I'd rather return an IQueryable and let callers compose those types of operations into the query (as long as you are IQueryable, a technology like EF or nHibernate can translate those operators into SQL - if you fall back to IList or IEnumerable it's all in memory operations).
Although I avoid paging and sorting I might have more specific operations on a repository to shield business logic from some details. For example, I might extend IEmployeeRepository from IRepository and add a GetManagers method, or something similar to hide the Where expression needed in the query. It all depends on the application and complexity level.
One important note on this sentence in your post:
Of course the Unit of Work would
inject a data context (Microsoft fan)
to the new repository, where the Unit
of Work would have a .Save() method,
calling Save on all data contexts.
Make sure you are using a single data context/object context inside each unit of work, because a context is essentially the underlying unit of work. If you are using multiple contexts in the same logic transaction then you'd effectively have multiple units of work.
I have a couple sample implementations in this project:
http://odetocode.com/downloads/employeetimecards.zip
The code might make more sense if you read this accompanying article:
http://msdn.microsoft.com/en-us/library/ff714955.aspx
Hope that helps,

Categories

Resources