I am about to start a small/medium sized project. I am by no means a software architect. But I tend to question every move I make at times, since I want to do things correct.
I found a way to implement a simple repository, and I wanted to know if this is a "correct" way of doing it. I came to this solution, since I know what is going on, and not taking in something to complex before I have the knowledge.
Unit of work
Where I make sure I to keep all my repositories under the same dbcontext. In my UOW I can access all repos when calling it from the controller.
public class UnitOfWork : IDisposable
{
private ContactRepository _contactRepo;
private ApplicationDbContext _entities;
public UnitOfWork(ApplicationDbContext entities)
{
_entities = entities;
}
public ContactRepository ContactRepo
{
get
{
if (_contactRepo == null)
{
_contactRepo = new ContactRepository(_entities);
}
return _contactRepo;
}
}
public void Save()
{
_entities.SaveChanges();
}
private bool disposed = false;
protected virtual void Dispose(bool disposing)
{
if (!this.disposed)
{
if (disposing)
{
_entities.Dispose();
}
}
this.disposed = true;
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
}
ContactRepository
This is a short example of a repository, where it receives the dbcontext and uses it to grab whatever data I want.
public class ContactRepository
{
private ApplicationDbContext _entities;
public ContactRepository(ApplicationDbContext entities)
{
_entities = entities;
}
public IEnumerable<Contact> GetAll()
{
return _entities.Contacts;
}
}
Controller
Short example of controller
public class ContactController : Controller
{
UnitOfWork uow = new UnitOfWork(new ApplicationDbContext());
public ActionResult Index()
{
var contacts = uow.ContactRepo.GetAll();
return View(contacts);
}
protected override void Dispose(bool disposing)
{
uow.Dispose();
base.Dispose(disposing);
}
}
In this way I will have access to all my repositories under the same dbcontext which I was aiming for.
I know things can be done smarter/different. With for example a extendable generic repo. But in this case I am aiming for something simple and understandable. But still don't want to make a huge mistake, if there is a major flaw.
Do you see any major flaws with this way of handling data through entity framework?
-
3\$\begingroup\$ "The single best reason to not use the repository pattern with Entity Framework? Entity Framework already implements a repository pattern." \$\endgroup\$BCdotWEB– BCdotWEB2016年05月23日 08:47:57 +00:00Commented May 23, 2016 at 8:47
-
1\$\begingroup\$ i am fully aware of entity framework having a built in repo. But having EF logic scattered across controllers can lead to a fully fledged maintenance hell. :) \$\endgroup\$Mathias Hove– Mathias Hove2016年05月23日 14:37:04 +00:00Commented May 23, 2016 at 14:37
-
1\$\begingroup\$ That answer also explains to "go with a service pattern, where you construct an API that your application can use without knowing or caring whether the data is coming from Entity Framework, NHibernate, or a Web API". \$\endgroup\$BCdotWEB– BCdotWEB2016年05月23日 15:11:24 +00:00Commented May 23, 2016 at 15:11
1 Answer 1
Keep your disposables short lived and you'll never have to implement IDisposable
yourself.
In other words, avoid keeping disposable objects as members. Always try to wrap them in a using
statement. If you do that, you'll find that your Unit of Work doesn't need to be disposable.
I can't ignore the obvious here though. There is no reason for any of this code to exist. It literally does nothing but pass through to the DbContext
. Entity Framework is already a repository & unit of work.
That's not to say that you shouldn't hide the fact that you're using EF from your controller though. It's much better to create a domain specific API to decouple your controller from the persistence. In our projects we'll often have things like FooService.GetByName(string name)
and FooService.GetMostRecent(int numberToRetrieve)
kinds of methods. It makes for pleasant reading and easy implementation changes.
Explore related questions
See similar questions with these tags.