I need guidance on designing data layer for my Web API services. The Web API controllers call the service layer which calls the data layer.
I am planning to use Entity Framework along with Dapper. It might not be a good solution to use both of them together, but I need both. I need EF as it is easier to use and developers in my team are familiar. I need Dapper for performance. So, it will be a mix depending on where the dapper can make significant impact and where we can compromise on being a little late.
When using EF, I wanted to use unit of work with repository for each entity. My repository will be like
public class StudentRepository : IStudentRepository, IDisposable
{
private SchoolContext context;
public StudentRepository(SchoolContext context)
{
this.context = context;
}
public IEnumerable<Student> GetStudents()
{
return context.Students.ToList();
}
}
I took that sample code from http://www.asp.net/mvc/overview/older-versions/getting-started-with-ef-5-using-mvc-4/implementing-the-repository-and-unit-of-work-patterns-in-an-asp-net-mvc-application
So, now I wanted to introduce Dapper.
Approach 1: Initially I thought of having multiple repositories for Dapper and for Entity Framework and I can register the one which I need in my dependency injection container. But in this case, all the methods from IStudentRepository interface needs to be implemented in both the EF and Dapper concrete repository classes (if I could do this in Dapper completely, then I don't need EF at all).
Approach 2 : Then I thought about a more ugly approach and it is like exposing a property of IDbConnection along with the DbContext property (in this case SchoolContext) in the above StudentRepository class.
So the example would be like
public class StudentRepository : IStudentRepository, IDisposable
{
private SchoolContext context;
private IDbConnection Db;
public StudentRepository(SchoolContext context)
{
this.context = context;
this.db = new SqlConnection(ConfigurationManager.ConnectionStrings["conn"].ConnectionString);
}
public IEnumerable<Student> GetStudents()
{
return context.Students.ToList();
}
public IEnumerable<Student> GetStudentsBasedOnSomeComplexCondition()
{
//I can use the db property here and work with dapper in this case.
}
(The inclusion of the IDbConnection property can be done through an abstract class so as not to repeat the instantiation code of this property and to easily change the connection string in case if needed. I am adding it in the same class for simplicity).
Approach 3 : Now, I thought of separating it further which I again think is an ugly way. Along with StudentRepository which has only EF stuff (like the first example), I will have another concrete class called StudentDapperRepository which inherits from StudentRepository.
All the methods in StudentRepository will be changed to virtual. So, I will be using StudentDapperRepository for my actual data layer and this will have the Dapper implementations where needed and where not needed, it will use the base class StudentRepository methods (which is in EF).
I think all my solutions are ugly and adding more complexity and confusion. So, can I have some light into how I can do this.
I am utilizing ASP.NET WebAPI 2 & EF6 for a very small project which utilizes AutoFac to inject my DbContext directly into my controllers. I am not using a repository pattern as per Ryan's answer here: NOT using repository pattern, use the ORM as is (EF). To perform the injection, I went ahead and created an interface like so:
public interface IMoveGroupEntities : IDisposable
{
System.Data.Entity.DbSet<HostEntry> HostEntries { get; set; }
DbEntityEntry<TEntity> Entry<TEntity>(TEntity entity) where TEntity : class;
Task<int> SaveChangesAsync();
}
Then implemented the interface on a partial class which sits in conjunction with my generated entities like so:
public partial class MoveGroupEntities : IMoveGroupEntities
{
}
I have a sneaking suspicion I'm doing something incorrectly here as I feel like this line:
DbEntityEntry<TEntity> Entry<TEntity>(TEntity entity) where TEntity : class;
Shouldn't be needed, but it does appear to be necessary as "Entry" is used from within my scaffolded API controller.
Can anyone chime in here on a better way to achieve this?
The best you can say about scaffolded code is: it works. It's not the best code architecturally. I fully agree with the link you quote, but that doesn't mean that the controllers should be in touch with EF artifacts directly (including Entry).
I think it's a mistake to replace one DbSet wrapper (repository) by another wrapper. The gist of the answer is: use the context (and DbSets, etc.) directly in your code. That is: don't use wrappers. That is not: use contexts (etc.) anywhere. You're doing the exact opposite: you create a different type of wrapper in order to use EF anywhere. But it's a good thing that your gut feeling doesn't really like it.
I always prefer to keep action methods (MVC, Web API) small. Basically, I just make them call a service method. It's the service that deals with contexts and everything EF has to offer. These services may be in a separate assembly, but wherever they are, they are injected into the controllers by dependency injection and, likewise, they obtain their contexts by DI.
I am about to implement an Entity Framework 6 design with a repository and unit of work.
There are so many articles around and I'm not sure what the best advice is: For example I realy like the pattern implemented here: for the reasons suggested in the article here
However, Tom Dykstra (Senior Programming Writer on Microsoft's Web Platform & Tools Content Team) suggests it should be done in another article: here
I subscribe to Pluralsight, and it is implemented in a slightly different way pretty much every time it is used in a course so choosing a design is difficult.
Some people seem to suggest that unit of work is already implemented by DbContext as in this post, so we shouldn't need to implement it at all.
I realise that this type of question has been asked before and this may be subjective but my question is direct:
I like the approach in the first (Code Fizzle) article and wanted to know if it is perhaps more maintainable and as easily testable as other approaches and safe to go ahead with?
Any other views are more than welcome.
#Chris Hardie is correct, EF implements UoW out of the box. However many people overlook the fact that EF also implements a generic repository pattern out of the box too:
var repos1 = _dbContext.Set<Widget1>();
var repos2 = _dbContext.Set<Widget2>();
var reposN = _dbContext.Set<WidgetN>();
...and this is a pretty good generic repository implementation that is built into the tool itself.
Why go through the trouble of creating a ton of other interfaces and properties, when DbContext gives you everything you need? If you want to abstract the DbContext behind application-level interfaces, and you want to apply command query segregation, you could do something as simple as this:
public interface IReadEntities
{
IQueryable<TEntity> Query<TEntity>();
}
public interface IWriteEntities : IReadEntities, IUnitOfWork
{
IQueryable<TEntity> Load<TEntity>();
void Create<TEntity>(TEntity entity);
void Update<TEntity>(TEntity entity);
void Delete<TEntity>(TEntity entity);
}
public interface IUnitOfWork
{
int SaveChanges();
}
You could use these 3 interfaces for all of your entity access, and not have to worry about injecting 3 or more different repositories into business code that works with 3 or more entity sets. Of course you would still use IoC to ensure that there is only 1 DbContext instance per web request, but all 3 of your interfaces are implemented by the same class, which makes it easier.
public class MyDbContext : DbContext, IWriteEntities
{
public IQueryable<TEntity> Query<TEntity>()
{
return Set<TEntity>().AsNoTracking(); // detach results from context
}
public IQueryable<TEntity> Load<TEntity>()
{
return Set<TEntity>();
}
public void Create<TEntity>(TEntity entity)
{
if (Entry(entity).State == EntityState.Detached)
Set<TEntity>().Add(entity);
}
...etc
}
You now only need to inject a single interface into your dependency, regardless of how many different entities it needs to work with:
// NOTE: In reality I would never inject IWriteEntities into an MVC Controller.
// Instead I would inject my CQRS business layer, which consumes IWriteEntities.
// See #MikeSW's answer for more info as to why you shouldn't consume a
// generic repository like this directly by your web application layer.
// See http://www.cuttingedge.it/blogs/steven/pivot/entry.php?id=91 and
// http://www.cuttingedge.it/blogs/steven/pivot/entry.php?id=92 for more info
// on what a CQRS business layer that consumes IWriteEntities / IReadEntities
// (and is consumed by an MVC Controller) might look like.
public class RecipeController : Controller
{
private readonly IWriteEntities _entities;
//Using Dependency Injection
public RecipeController(IWriteEntities entities)
{
_entities = entities;
}
[HttpPost]
public ActionResult Create(CreateEditRecipeViewModel model)
{
Mapper.CreateMap<CreateEditRecipeViewModel, Recipe>()
.ForMember(r => r.IngredientAmounts, opt => opt.Ignore());
Recipe recipe = Mapper.Map<CreateEditRecipeViewModel, Recipe>(model);
_entities.Create(recipe);
foreach(Tag t in model.Tags) {
_entities.Create(tag);
}
_entities.SaveChanges();
return RedirectToAction("CreateRecipeSuccess");
}
}
One of my favorite things about this design is that it minimizes the entity storage dependencies on the consumer. In this example the RecipeController is the consumer, but in a real application the consumer would be a command handler. (For a query handler, you would typically consume IReadEntities only because you just want to return data, not mutate any state.) But for this example, let's just use RecipeController as the consumer to examine the dependency implications:
Say you have a set of unit tests written for the above action. In each of these unit tests, you new up the Controller, passing a mock into the constructor. Then, say your customer decides they want to allow people to create a new Cookbook or add to an existing one when creating a new recipe.
With a repository-per-entity or repository-per-aggregate interface pattern, you would have to inject a new repository instance IRepository<Cookbook> into your controller constructor (or using #Chris Hardie's answer, write code to attach yet another repository to the UoW instance). This would immediately make all of your other unit tests break, and you would have to go back to modify the construction code in all of them, passing yet another mock instance, and widening your dependency array. However with the above, all of your other unit tests will still at least compile. All you have to do is write additional test(s) to cover the new cookbook functionality.
I'm (not) sorry to say that the codefizzle, Dyksta's article and the previous answers are wrong. For the simple fact that they use the EF entities as domain (business) objects, which is a big WTF.
Update: For a less technical explanation (in plain words) read Repository Pattern for Dummies
In a nutshell, ANY repository interface should not be coupled to ANY persistence (ORM) detail. The repo interface deals ONLY with objects that makes sense for the rest of the app (domain, maybe UI as in presentation). A LOT of people (with MS leading the pack, with intent I suspect) make the mistake of believing that they can reuse their EF entities or that can be business object on top of them.
While it can happen, it's quite rare. In practice, you'll have a lot of domain objects 'designed' after database rules i.e bad modelling. The repository purpose is to decouple the rest of the app (mainly the business layer) from its persistence form.
How do you decouple it when your repo deals with EF entities (persistence detail) or its methods return IQueryable, a leaking abstraction with wrong semantics for this purpose (IQueryable allows you to build a query, thus implying that you need to know persistence details thus negating the repository's purpose and functionality)?
A domin object should never know about persistence, EF, joins etc. It shouldn't know what db engine you're using or if you're using one. Same with the rest of the app, if you want it to be decoupled from the persistence details.
The repository interface know only about what the higher layer know. This means, that a generic domain repository interface looks like this
public interface IStore<TDomainObject> //where TDomainObject != Ef (ORM) entity
{
void Save(TDomainObject entity);
TDomainObject Get(Guid id);
void Delete(Guid id);
}
The implementation will reside in the DAL and will use EF to work with the db. However the implementation looks like this
public class UsersRepository:IStore<User>
{
public UsersRepository(DbContext db) {}
public void Save(User entity)
{
//map entity to one or more ORM entities
//use EF to save it
}
//.. other methods implementation ...
}
You don't really have a concrete generic repository. The only usage of a concrete generic repository is when ANY domain object is stored in serialized form in a key-value like table. It isn't the case with an ORM.
What about querying?
public interface IQueryUsers
{
PagedResult<UserData> GetAll(int skip, int take);
//or
PagedResult<UserData> Get(CriteriaObject criteria,int skip, int take);
}
The UserData is the read/view model fit for the query context usage.
You can use directly EF for querying in a query handler if you don't mind that your DAL knows about view models and in that case you won't be needing any query repo.
Conclusion
Your business object shouldn't know about EF entities.
The repository will use an ORM, but it never exposes the ORM to the rest of the app, so the repo interface will use only domain objects or view models (or any other app context object that isn't a persistence detail)
You do not tell the repo how to do its work i.e NEVER use IQueryable with a repo interface
If you just want to use the db in a easier/cool way and you're dealing with a simple CRUD app where you don't need (be sure about it) to maintain separation of concerns then skip the repository all together, use directly EF for everything data. The app will be tightly coupled to EF but at least you'll cut the middle man and it will be on purpose not by mistake.
Note that using the repository in the wrong way, will invalidate its use and your app will still be tightly coupled to the persistence (ORM).
In case you believe the ORM is there to magically store your domain objects, it's not. The ORM purpose is to simulate an OOP storage on top of relational tables. It has everything to do with persistence and nothing to do with domain, so don't use the ORM outside persistence.
DbContext is indeed built with the Unit of Work pattern. It allows all of its entities to share the same context as we work with them. This implementation is internal to the DbContext.
However, it should be noted that if you instantiate two DbContext objects, neither of them will see the other's entities that they are each tracking. They are insulated from one another, which can be problematic.
When I build an MVC application, I want to ensure that during the course of the request, all my data access code works off of a single DbContext. To achieve that, I apply the Unit of Work as a pattern external to DbContext.
Here is my Unit of Work object from a barbecue recipe app I'm building:
public class UnitOfWork : IUnitOfWork
{
private BarbecurianContext _context = new BarbecurianContext();
private IRepository<Recipe> _recipeRepository;
private IRepository<Category> _categoryRepository;
private IRepository<Tag> _tagRepository;
public IRepository<Recipe> RecipeRepository
{
get
{
if (_recipeRepository == null)
{
_recipeRepository = new RecipeRepository(_context);
}
return _recipeRepository;
}
}
public void Save()
{
_context.SaveChanges();
}
**SNIP**
I attach all my repositories, which are all injected with the same DbContext, to my Unit of Work object. So long as any repositories are requested from the Unit of Work object, we can be assured that all our data access code will be managed with the same DbContext - awesome sauce!
If I were to use this in an MVC app, I would ensure the Unit of Work is used throughout the request by instantiating it in the controller, and using it throughout its actions:
public class RecipeController : Controller
{
private IUnitOfWork _unitOfWork;
private IRepository<Recipe> _recipeService;
private IRepository<Category> _categoryService;
private IRepository<Tag> _tagService;
//Using Dependency Injection
public RecipeController(IUnitOfWork unitOfWork)
{
_unitOfWork = unitOfWork;
_categoryRepository = _unitOfWork.CategoryRepository;
_recipeRepository = _unitOfWork.RecipeRepository;
_tagRepository = _unitOfWork.TagRepository;
}
Now in our action, we can be assured that all our data access code will use the same DbContext:
[HttpPost]
public ActionResult Create(CreateEditRecipeViewModel model)
{
Mapper.CreateMap<CreateEditRecipeViewModel, Recipe>().ForMember(r => r.IngredientAmounts, opt => opt.Ignore());
Recipe recipe = Mapper.Map<CreateEditRecipeViewModel, Recipe>(model);
_recipeRepository.Create(recipe);
foreach(Tag t in model.Tags){
_tagRepository.Create(tag); //I'm using the same DbContext as the recipe repo!
}
_unitOfWork.Save();
Searching around the internet I found this http://www.thereformedprogrammer.net/is-the-repository-pattern-useful-with-entity-framework/ it's a 2 part article about the usefulness of the repository pattern by Jon Smith.
The second part focuses on a solution. Hope it helps!
Repository with unit of work pattern implementation is a bad one to answer your question.
The DbContext of the entity framework is implemented by Microsoft according to the unit of work pattern. That means the context.SaveChanges is transactionally saving your changes in one go.
The DbSet is also an implementation of the Repository pattern. Do not build repositories that you can just do:
void Add(Customer c)
{
_context.Customers.Add(c);
}
Create a one-liner method for what you can do inside the service anyway ???
There is no benefit and nobody is changing EF ORM to another ORM nowadays...
You do not need that freedom...
Chris Hardie is argumenting that there could be instantiated multiple context objects but already doing this you do it wrong...
Just use an IOC tool you like and setup the MyContext per Http Request and your are fine.
Take ninject for example:
kernel.Bind<ITeststepService>().To<TeststepService>().InRequestScope().WithConstructorArgument("context", c => new ITMSContext());
The service running the business logic gets the context injected.
Just keep it simple stupid :-)
You should consider "command/query objects" as an alternative, you can find a bunch of interesting articles around this area, but here is a good one:
https://rob.conery.io/2014/03/03/repositories-and-unitofwork-are-not-a-good-idea/
When you need a transaction over multiple DB objects, use one command object per command to avoid the complexity of the UOW pattern.
A query object per query is likely unnecessary for most projects. Instead you might choose to start with a 'FooQueries' object
...by which I mean you can start with a Repository pattern for READS but name it as "Queries" to be explicit that it does not and should not do any inserts/updates.
Later, you might find splitting out individual query objects worthwhile if you want to add things like authorization and logging, you could feed a query object into a pipeline.
I always use UoW with EF code first. I find it more performant and easier tot manage your contexts, to prevent memory leaking and such. You can find an example of my workaround on my github: http://www.github.com/stefchri in the RADAR project.
If you have any questions about it feel free to ask them.
I'm having a difficult time finding straight forward examples of using EF in a DDD style pattern. This is also my first time employing DDD and have a few questions regarding solution layout and how to employ some of the DDD patterns.
1) Most of the examples I've seen regarding using the Repository pattern w/ EF just show specialized Model interfaces such as IContactRepository and then a concrete type implementing the interface. Ideally, I'd love to use something like IRepository that has a basic set of functionality for CRUD ops. I could then create specialized repositories if if necessary such as IContactRepository : IRepository when necesary as most of my models won't need to be extended. Am I barking up the wrong tree? Can someone provide me w/ examples of this style of implementation?
2) Right now I have my solutio broken up into the following three projects: Models (contains my EDM), Repositories, and Services. Is this fitting or is there another layout approach I'm not considering and should be?
3) I've seen examples of repositories having a Query(Func<T>)/Query() methods that return IQueryable. Is this smelly or something frowned upon?
I'd like to answer #3...
I think it's less "smelly" and more "lazy". Here's a typical "repository" that I've been seeing around the internets...
public interface IRepository {
// Query operations.
IQueryable<T> All<T>();
IQueryable<T> Find<T>(Expression<Func<T, bool>> expression);
T Single<T>(Expression<Func<T, bool>> expression);
// Save operations.
T Add<T>(T objectToAdd);
void Delete<T>(T objectToDelete);
T Update<T>(T objectToUpdate);
}
As far as I'm aware, this is less a repository and more a "session" or "unit of work". It's a handy way to abstract away whatever database technology you're using and just talk to an extremely generic interface instead. So let's rename it to an ISession, instead. This is the pattern I've been doing recently.
public class PeopleRepository {
private readonly ISession session;
public PeopleRepository(ISession session) {
this.session = session;
}
public virtual IEnumerable<Person> Active() {
return session.Find<Person>(p => p.Active).OrderBy(p => p.LastName).ThenBy(p => p.FirstName);
}
public virtual IEnumerable<Person> ByLastName(string name) {
return session.Find<Person>(p => p.Active && p.LastName.StartsWith(lastName)).OrderBy(p => p.LastName).ThenBy(p => p.FirstName);
}
public virtual void DeletePerson(int personId) {
// We don't really delete people; we mark them as inactive.
var person = session.Single<Person>(p => p.Id == personId);
person.Active = false;
session.Update(person);
}
}
In this setup, the ISession is a generic link to the data store. The PersonRepository, however, is very specific to the types of queries and actions that are taken on a Person object.
Hope this helps.
We are currently using EF with DDD, but I would have to say that in its current implementation, EF isn't very suitable to this kind of architecture. The main problem is that the only way EF currently works is by having each 'Entity' derive from an EF-specific base class.
On the other hand, the whole point about Repositories is to abstract away the data access technology. The whole idea behind DDD is that the Domain Model should be unconstraind by implementation details such as the choice of data access technology. This means that domain objects should be defined so that they are Persistence-Ignorant.
In other words: You can't use the EF 'Entities' as domain objects, so in your DAL, you must manually write a lot of code that maps to and from the domain objects to the EF 'Entities'. That gets tired really fast.
I would definitely consider having IQueryable on a Repository to be a leaky abstraction, and it doesn't make a lot of sense in DDD parlance. If domain objects are cohesive units, it doesn't make a whole lot of sense selecting only certain 'columns' from them.
In EF for .NET 4.0 we will get Persistence Ignorance, so it should become better in the future...
Here is a sample:
http://dataguidance.codeplex.com/
Although I'm not doing full blown DDD, I find the repository pattern appealing and I do try to segment the repositories along aggregate-root boundaries. I'm implementing repositories on top of the Entity Framework, and here the ObjectContext allows for a unit-of-work style as it tracks changes to the entities and will generate the appropriate SQL when SaveChanges is called.
I'm struggling with two different approaches within my repositories around when to call SaveChanges -- and the difference seems to be whether I'm adopting unit-of-work or active record semantics. If I define a repository interface to look like this:
public interface IRepository<T>
{
T Get(int id);
IList<T> GetAll();
IQueryable<T> Query();
void Delete(T entity);
void Add(T entity);
IUnitOfWork GetUnitOfWork();
}
and IUnitOfWork to be
public interface IUnitOfWork
{
void SaveChanges();
}
Then in the Add(T entity) implementation, I seem to have two choices:
public void Add(Document entity)
{
DB.AddToDocumentSet(entity);
GetUnitOfWork().SaveChanges(); //delegates to the ObjectContext's SaveChanges
}
or
public void Add(Document entity)
{
DB.AddToDocumentSet(entity);
}
In the former case, the repository's Add method is sending the SQL on each operation. In the latter case, the calling code is responsible for obtaining the unit of work from the repository and calling SaveChanges when it deems appropriate. This allows the unit of work to span different repositories (I'm ensuring that each repository gets the same unit of work in its construction).
My gut feel is that the second approach is more flexible. Adopting the unit of work pattern also means that updates to entities are a bit nicer in that calling code simply updates properties on entities returned by the repositories and then calls UnitOfWork.SaveChanges.
When using the repository pattern, is one approach generally favored over the other?
It depends on your failure mode requirements, which you haven't stated. This is primarily an issue of how to handle failures that occur during your unit of work. You have basically two choices, although there are other more complex variants possible:
Save all changes that occurred during the unit of work up until the failure.
Rollback all changes that occurred during the unit of work due to the failure.
Your first Add method is more appropriate for scenario 1 and your second Add method is more appropriate for scenario 2.
Scenario 1 likely requires smart application code to allow the user to resume at the point of failure. Scenario 2 is easier to implement on the application side, but may frustrate the user if they were, for instance, 8 steps into a 9 step process when it failed.