I am trying to implement a generic repository pattern. I found this site which I think its well explained.
http://www.tugberkugurlu.com/archive/generic-repository-pattern-entity-framework-asp-net-mvc-and-unit-testing-triangle
My purpose is to save the developers some time and keystrokes and I know this will help me.
So I have 2 questions:
1. Is this a good approach or not, will I have some problems in the future?
2. How can I combine it with Unitofwork pattern?, I cant create an instance of the abstract class of course, so the following code its invalid.
public class UnitOfWork : IDisposable
{
#region Private fields
private readonly MyCompanyContext _context = new MyCompanyContext();
private GenericRepository<MyCompanyContext, Task> _taskRepository;
public GenericRepository<MyCompanyContext, Task> TaskRepository
{
get
{
return _taskRepository ??
(_taskRepository = new GenericRepository<MyCompanyContext, Task>());
}
}
namespace MyCompany.DAL.Repository
{
public interface IGenericRepository<T> where T : class
{
IQueryable<T> GetAll();
IQueryable<T> FindBy(Expression<Func<T, bool>> predicate);
void Add(T entity);
void Delete(T entity);
void Edit(T entity);
void Save();
}
public abstract class GenericRepository<C, T> :
IGenericRepository<T>
where T : class
where C : DbContext, new()
{
private C _entities = new C();
public C Context
{
get { return _entities; }
set { _entities = value; }
}
public virtual IQueryable<T> GetAll()
{
IQueryable<T> query = _entities.Set<T>();
return query;
}
public IQueryable<T> FindBy(System.Linq.Expressions.Expression<Func<T, bool>> predicate)
{
IQueryable<T> query = _entities.Set<T>().Where(predicate);
return query;
}
public virtual void Add(T entity)
{
_entities.Set<T>().Add(entity);
}
public virtual void Delete(T entity)
{
_entities.Set<T>().Remove(entity);
}
public virtual void Edit(T entity)
{
_entities.Entry(entity).State = System.Data.EntityState.Modified;
}
public virtual void Save()
{
_entities.SaveChanges();
}
}
}
There are several opinions regarding repositories, but after trying various repository implementations in production for couple years myself, I agree with Ayende's opinion, that repository, especially generic, is redundant abstraction layer.
I liked very much this course:
http://www.pluralsight-training.net/microsoft/Courses/TableOfContents/linq-architecture
It walked through most possible solutions and explained goods and bads.
What we're using right now is very thin abstraction over datacontext, just to overcome Linq2Sql testability issues, which are irrelevant in most cases when using EF.
With a lot of effort you might get that working, but I wonder if the effort is really worth it? I've seen implementations like this before, and they really struggle when attempting to manage many-to-many relationships (have a think about how you'd manage that in your scenario).
You are using Entity Framework, an ORM right? ORMs like Entity Framework and nHibernate are designed to abstract the database implementation from application code, so what is the purpose of adding yet another abstraction above it to manage entities at such a granular level? If it's a question of testing, then you can use a mocking framework to mock the context, thus removing the need for an actual database during testing. If however, for architectural or security reasons you are seeking to remove interactions with a db context from your app code, I'd recommend for pragmatism using an implementation of the command pattern over the top of the entity framework. I've needed to do this on a larger scale enterprise (banking) application where for security reasons (rightly or wrongly) we were absolutely not allowed to have a db connection in our application code.
Related
Should I use these 5 methods, only? Or should my Repository show all of the sql methods I am requiring. Perhaps I misunderstand the examples. Should I FindByID and and FindAll? For example, if I have 5 dropdowns. I have 5 methods, or I may have one method, 5 queries, and return 1 table and bind to 0-4 tables.
What I have tried, is several lessons online and several articles and I still feel like the examples are over simplified. Or, I am writing way too many methods to query the db.
BTW, I am moving from linear development to repositories and factories. so, my transition is predicated on understanding this and then I would move to EF, and MVC.
public interface IRepository<T> where T: IEntity
{
void Insert(Student student);
void Delete(Student student);
void Update(Student student);
Student GetById(Student RollNo);
IQueryable<Student> FetchAll();
}
For simple entities and aggregates having a standard set of CRUD operations on your repository makes a lot of sense. However, for less standard aggregates and complicated operations it doesn't make sense to implement these common operations.
For example: Suppose before you want to add your student to the database, you need to make some complicated validation over that student and hide those details over the client.
Preferably, I like to use the DBContext directly. It gives me more free space to do whatever i need without thinking too much for adding that method to the interface, and go to implement it.
Anyway if you want to use Repository pattern. I recommend to use the generic one such as the following:
public class Repository<TEntity> : IRepository<TEntity> where TEntity : class, IEntity
{
private readonly CrudContext _context;
private readonly DbSet<TEntity> _dbSet;
public Repository(CrudContext context)
{
this._context = context;
this._dbSet = context.Set<TEntity>();
}
public IEnumerable<TEntity> List()
{
return _dbSet.ToList();
}
public TEntity GetById(int id)
{
return _dbSet.Find(id);
}
public void Insert(TEntity entity)
{
_dbSet.Add(entity);
_context.SaveChanges();
}
public void Update(TEntity entity)
{
_dbSet.Attach(entity);
_context.Entry(entity).State = EntityState.Modified;
_context.SaveChanges();
}
public void Delete(int id)
{
var entityToDelete = _dbSet.Find(id);
_dbSet.Remove(entityToDelete);
_context.SaveChanges();
}
}
If it comes to my preference, Either I would use the dbcontext directly inside the dependent class or I would create an Interface called IEntityInserter and for each Record type or Model that has too much logic of inserting, I would create an implementation called
StudentBasedEntityInserter : IEntityInserter<Student> {
public void Insert(Student #student){}
}
and inject that IEntityInserter in any dependent class.
Finally, There is not right answers int that heated topic, some people would agree with my approach, others won't. Hope that it helps.
I'm designing an in-house enterprise application to manage small business loans using ASP.NET (C#), nHibernate, and an SQL Server in the back.
From much of the reading I've done, it seems to be fairly common practice to have separate repositories (as well as separate Service layer objects) for each domain object - which just seems like a lot of overkill and overhead to me.
With that in mind, I have a basic repository interface and a generic repository class based off of that to be used for domain objects that don't have 'special requirements' other than the basic CRUD operations (which are handled using ISession and ITransaction, code omitted)
// Repository interface:
public partial interface IRepository<T>
{
void Add(T entity);
void Update(T entity);
void Remove(T entity);
ICollection<T> GetAll();
T GetByKey(int _ID);
}
// Generic repository - basic CRUD for most domain objects
public partial class BaseRepository<T> : IRepository<T>
{
protected ISession session;
...
public virtual void Add(T entity)
{ ... }
public virtual void Update(T entity)
{ ... }
public virtual void Remove(T entity)
{ ... }
public virtual ICollection<T> GetAll()
{ ... }
public virtual T GetByKey(int _ID)
{ ... }
}
As stated, rather than having code for a couple dozen repositories with pretty much identical code other than the <type>, I would like to be able to use this BaseRepository class as the business object for an ObjectDataSource, but it is not showing up as an available option in the 'Configure Data Source' dialog.
Is it even possible to use a generic for this purpose? For any ASP.NET MVC gurus out there - is this something that is more easily handled using that framework over just ASP.NET?
I have the following fake repository that I use for unit testing. How would I implement the Attach(T entity) method in this repository?
(In my real repository, the Attach(T entity) method is used to attach an object to my Entity Framework 4 data context).
public class FakeRepository<T> : IRepository<T> where T : class, new()
{
private static List<T> entities = new List<T>();
public IQueryable<T> Entities
{
get { return entities.AsQueryable(); }
}
public T New()
{
return new T();
}
public void Create(T entity)
{
entities.Add(entity);
}
public void Delete(T entity)
{
entities.Remove(entity);
}
public void Attach(T entity)
{
//How to implement Attach???
}
public void Save()
{
//Do nothing
}
public void Dispose()
{
return;
}
}
To answer this, you have to ask yourself "what is the purpose of "Attach?" You probably know that the point is to tell the repository "this object is persisted in the database but you aren't currently tracking it; I have made updates to it and I want you to commit them when I tell you to submit your changes."
Thus, to test that Attach is working properly, you should maintain a collection of attached objects and add an entity to this collection when it is passed a parameter to Attach.
So, the simplest implementation would be
entities.Add(entity);
but you could consider something more fine-grained. Note that you need to expose a method that lets you assert that the entity was successfully attached (in EF4 you can use ObjectStateManager.TryGetObjectStateEntry).
get rid of the static word on the entities member. Now just do
enitities.Add(entity)
What is the best approach to implement a CRUD on the BL using interface that will be used to abstract DAL operations? I need your opinion guys..
Here's my draft..
Data Entities that are mapped in the database table
public class Student
{
public string StudentId { get; set; }
public string StudentName { get; set; }
public Course StudentCourse { get; set; }
}
public class Course
{
public string CourseCode { get; set; }
public string CourseDesc { get; set; }
}
I created an CRUD Interface to abstract the object's operations
public interface IMaintanable<T>
{
void Create(T obj);
T Retrieve(string key);
void Update(string key);
void Delete(string key);
}
And then a component that manages the Entity and its operations by implementing the interface
public class StudentManager : IMaintainable<Student>
{
public void Create(Student obj)
{
// inserts record in the DB via DAL
}
public Student Retrieve(string userId)
{
// retrieveds record from the DB via DAL
}
public void Update()
{
// should update the record in the DB
}
public void Delete(string userId)
{
// deletes record from the DB
}
}
sample usage
public void Button_SaveStudent(Event args, object sender)
{
Student student = new Student()
{
StudentId = "1", StudentName = "Cnillincy"
}
new StudentManager().Create(student);
}
as you can see, there is quite an abnormalities on the update method
public void Update()
{
// should update the record in the DB
}
what should this method have to update the objects property? should I inherit the Student?
public class StudentManager : Student , IMaintainable<Student>
{
public void Update()
{
//update record via DAL
}
}
public void Button_SaveStudent(Event args, object sender)
{
Student student = new StudentManager();
student.StudentId = "1";
student.StudentName = "Cnillincy"
student.Update()
}
Or should I just contain the Student class as an attribute of the Student manager?
public class StudentManager : IMaintainable<Student>
{
public Student student { get; private set };
public void Create() {}
public void Update() {}
public void Retrieve() {}
public void Delete() {}
}
Which more appropriate? What about the interface? Any other suggestions guys? thanks..C
Your CRUD interface should probably look like
public interface IMaintanable<T>
{
string Create(T obj);
T Retrieve(string key);
void Update(T obj);
void Delete(string key);
}
that is, both Create and Update take a copy of the object you're updating. The difference is that the Update can get the key from the obj, so it knows which object it's changing. Create would normally cause the key to be created so you pass it back as a return value. Hope that helps.
(The Update might also pass back the key too.)
Personally, I think that all you are missing is the appropriate terminology. What this really is an approximation of a very helpful pattern, called the repository pattern. As far as type-awareness, goes, the implementation would be referred to as a generic repository.
The way I have personally implemented in the past was to have an interface defining the repository, such as IRepository<T>, and a base class that is specific to the type of repository, such as a SqlRepositoryBase<T>. The reason that I would do this is that I can put the implementation-specific code in the base class. So, the plumbing is done and I can worry about domain-specific implementation in the final repository, which would be StudentRepository, a SqlRepository<Student> (or SqlRepository<IStudent> if you define interfaces for your entity).
It seems that you are concerned about how many objects are instansiated, and I can tell you that you are not generating a significant enough drain on resources to really be concerned about implementing in this fashion. Old-timers might cringe at the fact, but we are not trying to optimize for 64k or RAM anymore. ;-) It is more about maintainability, code contracts, etc.
Not to add uneeded complexity up-front, but you also might want to look into the Unit of Work Pattern if you are looking at enlisting multiple entities of different types into atomic transactions.
Here are a couple of good references for these topics:
new Repository().DoMagic()
The Unit of Work Pattern
Two takeaways from this in general (IMHO):
I personally disagree with the assumption that a Repository pattern approach only has usefulness in larger projects; especially the Generic Repository pattern. If you start putting code like this into a reusable library, you will be surprised at how quickly you can start creating an invaluable resource of building blocks.
The biggest plus from this approach is the sheer testability of it; even more so than the reusability. If you are looking to mock out your repositories for any sort of a TDD approach, you can do so with little effort. This will allow you to write richer tests around the usages of the repositories throughout your code.
I saw this from Rob Conery that I really like. It's power is in the flexibility of the arguments you can pass to the methods. Your implimentation isn't robust enough IMO. Check out his MVC starter kit here http://mvcstarter.codeplex.com/ (It's called ISession there).
public interface IMaintainable : IDisposable
{
T Single<T>(Expression<Func<T, bool>> expression) where T : class, new();
System.Linq.IQueryable<T> All<T>() where T : class, new();
void Add<T>(T item) where T : class, new();
void Update<T>(T item) where T : class, new();
void Delete<T>(T item) where T : class, new();
void Delete<T>(Expression<Func<T, bool>> expression) where T : class, new();
void DeleteAll<T>() where T : class, IEntity, new();
void CommitChanges();
}
I wouldn't make StudentManager inherit Student, I would make my Update method stateless like your create method, i.e.
public interface IMaintanable<T>
{
void Create(T obj);
T Retrieve(string key);
void Update(T obj);
void Delete(string key);
}
and
public void Update(T obj)
{
// should update the record in the DB
}
Take a look at the new Entity Framework 4 that was recently released. They are featuring a "code by convention" model that allows you to easily map your business objects directly to the database without having to worry about a DAL.
"The Gu" has a great series outlining how easy it is to map your objects, and even do some simple modifications when linking to the database through the DbContext model it uses.
It is worth noting that the current release is at CTP4, but I anticipate most of the issues have already been worked out with the framework and should serve you well.
I changed the responses here a little bit, to this:
public interface IMaintanable<T>
{
Guid Create(T obj);
T Read(Guid key);
bool Update(T obj);
bool Delete(Guid key);
}
This interface is based on my database structure. I use Guids for primary keys.
I'm currently developing a medium sized application, which will access 2 or more SQL databases, on different sites etc...
I am considering using something similar to this:
http://mikehadlow.blogspot.com/2008/03/using-irepository-pattern-with-linq-to.html
However, I want to use fluent nHibernate, in place of Linq-to-SQL (and of course nHibernate.Linq)
Is this viable?
How would I go about configuring this?
Where would my mapping definitions go etc...?
This application will eventually have many facets - from a WebUI, WCF Library and Windows applications / services.
Also, for example on a "product" table, would I create a "ProductManager" class, that has methods like:
GetProduct, GetAllProducts etc...
Any pointers are greatly received.
In my opinion (and in some other peoples opinion as well), a repository should be an interface that hides data access in an interface that mimics a collection interface. That's why a repository should be an IQueryable and IEnumerable.
public interface IRepository<T> : IQueryable<T>
{
void Add(T entity);
T Get(Guid id);
void Remove(T entity);
}
public class Repository<T> : IQueryable<T>
{
private readonly ISession session;
public Repository(ISession session)
{
session = session;
}
public Type ElementType
{
get { return session.Query<T>().ElementType; }
}
public Expression Expression
{
get { return session.Query<T>().Expression; }
}
public IQueryProvider Provider
{
get { return session.Query<T>().Provider; }
}
public void Add(T entity)
{
session.Save(entity);
}
public T Get(Guid id)
{
return session.Get<T>(id);
}
IEnumerator IEnumerable.GetEnumerator()
{
return this.GetEnumerator();
}
public IEnumerator<T> GetEnumerator()
{
return session.Query<T>().GetEnumerator();
}
public void Remove(T entity)
{
session.Delete(entity);
}
}
I do not implement a SubmitChanges like method in the repository itself, because I want to submit the changes of several repositories used by one action of the user at once. I hide the transaction management in a unit of work interface:
public interface IUnitOfWork : IDisposable
{
void Commit();
void RollBack();
}
I use the session of an NHibernate specific unit of work implementation as session for the repositories:
public interface INHiberanteUnitOfWork : IUnitOfWork
{
ISession Session { get; }
}
In a real application, I use a more complicated repository interface with methods for things like pagination, eager loading, specification pattern, access to the other ways of querying used by NHiberante instead of just linq. The linq implementation in the NHibernate trunk works good enough for most of the queries I need to do.
Here are my thoughts on generic repositories:
Advantage of creating a generic repository vs. specific repository for each object?
I have successfully used that pattern with NHibernate, and haven't found any real shortcomings.
The gist is that truly generic repositories are a bit of a red herring, but the same benefits can be realized by thinking about the problem slightly differently.
Hope that helps.