I'm starting a new web project using ASP.NET Webforms + EF4. I'm trying to apply a repository pattern with a unit of work pattern following this tutorial : http://www.dotnetage.com/publishing/home/2011/07/05/6883/the-repository-pattern-with-ef-code-first-dependeny-injection-in-asp-net-mvc3.html
I think I got the idea but my question is that, when I create a new object in the model, do I also have to define that object in IDALContext of the Unit Of Work? Isn't that a handbreak for rapid development? Also if you work with multiple developers and if you don't want other developers to see your DAL, how can you manage this? Because in this pattern as I understand, when you create a new object in the model you also have to define it in the IDALContext for this tutorial. Sorry I'm so confused by this.
Not necessarily. EF already provides the unit of work pattern for you. The only reason to still have a unit of work is if you: want to include non-EF-datasources in an atomic data operation.
The Repository pattern makes it easier to test your application logic. The Repository pattern allows you to easily test your application with unit tests. Remember that unit tests only test your code, not infrastructure, so the repository abstractions make it easier to achieve that goal.
No, the repository/unit-of-work pattern (shortened to Rep/UoW) isn't useful with EF Core. EF Core already implements a Rep/UoW pattern, so layering another Rep/UoW pattern on top of EF Core isn't helpful.
Unit of Work is the concept related to the effective implementation of the repository pattern. non-generic repository pattern, generic repository pattern. Unit of Work is referred to as a single transaction that involves multiple operations of insert/update/delete and so on.
Now, the first question should be, why do I need a repository or unit of work pattern at all? Couldn't I just use the EF context from the controller, having the full power of directly writing the query I need and returning the data?
Answer: You could, but the real intent behind is testability and thus higher quality, more maintainable code. If you separate your data access and concentrate it on one place, you can mock it out during testing. This allows you to unit test the logic defined within your controller without effectively writing to a data store.
Before starting with the Unit of Work, just use take a look at the Repository pattern. This basically abstracts the data access for a given entity. So you define methods like Filter(), All(), Update(..), Insert(..), Delete(...) and finally, Save(). Actually most of these could be quite easily abstracted to a BaseRepository<TEntity>
class such that in the end you'd just have to create a new Repository in rare cases with special behavior. Otherwise it would be something like BaseRepository<Person> personRepo = new BaseRepository<Person>()
or BaseRepository<Address> addressRepo = new BaseRepository<Address>()
etc.
Why is the Unit of Work needed?
A unit of work represents all operations done during a certain cycle, in a web environment normally per Http request. This means when a new request enters, you instantiate a new Unit of Work, you add new stuff, update or delete it and then you "commit" the changes by invoking the .save()
or .commit()
..whatever. Actually if you take a closer look at the Entity Framework DbContext (or ObjectContext), they are already representing some kind of Unit of Work.
However if you want to further abstract it, because you'd not necessarily like to have your EF context in your controller classes (remember: testability), then you create a UoW to group your Repositories and also to ensure they all share the same EF context instance. You might achieve the latter also through a DI container (Dependency Injection container).
To your questions: Is it useful in big projects?:
Definitely, especially in big projects. It's all about keeping responsibilities separated (data access, business logic, domain logic) and thus making things testable.
Martin Fowler describes the repository's role as: "A Repository mediates between the domain and data mapping layers, acting like an in-memory domain object collection". What Entity Framework 4.1 exposes is a repository in that sense. Also EF has a unity of work built in. So my advice is to ignore the blog article you mentioned in your question.
Code like this is not just only useless or worthless but dangerous because there is no benefit added to your code but a dependency!
public interface IUnitOfWork:IDisposable { int SaveChanges(); } public interface IDALContext : IUnitOfWork { ICategoryRepository Categories { get; } IProductRepository Products { get; } }
To answer your question having some abstraction that mediates between the domain and data mapping layers, acting like an in-memory domain object collection is a must for "big" projects. And having a UnitOfWork mechanism under the hood can help decouple your business logic from access to a some data access abstraction.
TL;TR; Repository and UnitOfWork can help you but don't apply it like in the given blog post.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With