Repository pattern interfaces- Best practices? [closed] - c#

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 8 years ago.
Improve this question
I'm learning about Repository Pattern and I found many code examples but all are almost the same so I have doubts to that respect, for example this design:
public interface IRepository<T>
{
void Add(T entity);
void Update(T entity);
void Delete(T entity);
IList<T> GetAll();
}
public interface IPostRepository
{
int GetComentCount();
}
public class EFRepository<T>: IRepository<T>
{
public void Add(T entity){ /*implementation...*/ }
public void Update(T entity){ /*implementation...*/ }
public void Delete(T entity){ /*implementation...*/ }
public IList<T> GetAll(){ /*implementation...*/ }
}
public class PostRepository: EFRepository<Post>, IPostRepository
{
public int GetComentCount(){ /*implementation...*/ }
}
public class UnitOfWork: IUnitOfWork, IDisposable
{
IPostRepository PostRepository {get;}
}
I can do this:
IUnitOfWork UoW = new UnitOfWork();
int nComments = UoW.PostRepository.GetComentCount();
but not this: (obviously)
var collection = UoW.PostRepository.GetAll();
What I have to do? Must I create another property in UoW and return an IRepository?
Must I create an interface for every Repository with no CRUD operations (for example IPostRepository)? Must a concrete repository inherit from EFRepository class and the interface at a time (for example: class PostRepository: EFRepository, IPostRepository{})?
What do you think?
PD: Pardon my poor english.

If you change IPostRepository to inherit from IRepository, you are simply extending the interface surface, so you don't need to redefine all the methods.
For example, with this change:
public interface IRepository<T>
{
void Add(T entity);
void Update(T entity);
void Delete(T entity);
IList<T> GetAll();
}
public interface IPostRepository : IRepository<int>
{
int GetComentCount();
}
public class EFRepository<T> : IRepository<T>
{
public void Add(T entity) { Console.WriteLine("Works"); }
public void Update(T entity) { /*implementation...*/ }
public void Delete(T entity) { /*implementation...*/ }
public IList<T> GetAll() { return null; }
}
public class PostRepository : EFRepository<int>, IPostRepository
{
public int GetComentCount() { return 0; }
}
public interface IUnitOfWork
{
}
public class UnitOfWork : IUnitOfWork, IDisposable
{
public IPostRepository PostRepository { get { return new PostRepository(); } }
public void Dispose()
{
throw new NotImplementedException();
}
}
The following code will print Works:
UnitOfWork t = new UnitOfWork();
t.PostRepository.Add(1);
Basically, your PostRepository does not need to reimplement the Add/Update/Delete methods as that interface contract is already present in the base class EFRepository and will be used. IPostRepository will force you to only provide the extended interface contract.
As for best practices, I don't think there is a single good solution. I try to go with the inherit approach, but I have seen good production code that has ReadOnly/Add/AddUpdate/etc. repository interfaces for composition.
P.S. I changed Post class with int in the example to avoid defining a whole new class.

Related

how to reference the Type in the Concrete class of a generic class

I found the following example, to which I have a follow up question.
stack overflow question
the existing code from the question is
public interface IRepository<T> where T : EntityObject
{
RepositoryInstructionResult Add(T item);
RepositoryInstructionResult Update(T item);
RepositoryInstructionResult Delete(T item);
}
public class Repository<T> : IRepository<T> where T : EntityObject
{
virtual RepositoryInstructionResult Add(T item)
{ //implementation}
virtual RepositoryInstructionResult Update(T item);
{ //implementation}
virtual RepositoryInstructionResult Delete(T item);
{ //implementation}
}
public class BarRepository : Repositorybase<Bar>
{
public override RepositoryInstructionResult Update(Bar item);
{
//Call base method if needed
//Base.Update(item);
//implement your custom logic here
}
}
what I would like to do is change the Update method to something like
public class BarRepository : Repositorybase<Bar>
{
// T is of Type Bar
public override RepositoryInstructionResult Update(T item);
{
//implement your custom logic here
}
}
Question: is there a way to expose the generic type in BarResposity : Repositorybase<Bar> to the methods in BarRepository?
looking for a better alternative to "search and replace" when building out the concrete class (eg make a copy of BarRespository as FooRepository and change all references from Bar to Foo). I would rather change the type in one place only.
(edit) Usage needs to remain as
var obj = new BarRepository();
Just as a note, if you're going to override all Add/Update/Delete anyways, you can make them as abstract in the RepositoryBase and then the vs suggestion is your friend:
and if there is shared logic between all of concrete classes you can put it in the abstract class and override abstract protected methods instead.
edit:
op asked for code that can do it.. well this should work.. but if you want a new concrete implementation, you'll have to create 2 classes now
public class BarRepository<T> : RepositoryBase<T> where T : Bar
{
public override int Add(T item)
{
throw new NotImplementedException();
}
public override int Update(T item)
{
throw new NotImplementedException();
}
public override int Delete(T item)
{
throw new NotImplementedException();
}
}
public class BarRepository : BarRepository<Bar>
{
}
also, if classes are so similar that copy-paste and replace is enough, maybe logic shouldn't be in separate classes but in the generic class? could you give an example of 2 classes maybe?
edit 2: another dirty trick would be to use lambdas, though personally I don't know if I would do it:
public abstract class RepositoryBase<T>
{
public Func<T, int> Add { get; protected set; }
public Func<T, int> Update { get; protected set; }
public Func<T, int> Delete { get; protected set; }
}
public class BarRepository : RepositoryBase<Bar>
{
public BarRepository()
{
Add = i => 6;
Update = i => 7;
Delete = i => 8;
}
}
It's a bit of a hack, but you could use a using alias to define the entity type:
using MyType = Bar;
public class BarRepository : Repositorybase<MyType>
{
public override RepositoryInstructionResult Update(MyType item);
{
return base.Update(item);
}
}
Now when you copy to Foo.cs, you can just change the using directive to
using MyType = Foo;
But, I would look to try and reuse as much generic code as possible, as it's not clear at all what MyType is just by looking at the methods. There's nothing wrong with a find.replace to define a new repository type that customizes actions - you just want to keep the repeated to a minimum.
IMHO any GENERIC repository is a waste of time, but if you decide to use it , what is wrong with this
public class BarRepository<T> : Repository<Bar> where T : class
{
public override void Update(Bar item)
{
}
public void Update(T item)
{
}
}
UPDATE
It looks weird but since OP wants it , you can create this code too
public class BarRepository<T> : Repository<Bar> where T : Bar
{
public override void Update(Bar item)
{
Console.WriteLine("it is Bar");
}
// T is of Type Bar
public void Update(T item)
{
Console.WriteLine("it is T");
}
}
tests
public class Bar { }
public class NoBar { }
var barRep= new BarRepository<Bar>();
barRep.Update(new Bar()); // "it is T"
var noBarRep= new BarRepository<NoBar>(); // ERROR!
UPDATE 2
since if you want
var rep = new BarRepository();
var result= rep.Update(new Bar());
you can do it the way you have done already
public class BarRepository : Repositorybase<Bar>
{
public override RepositoryInstructionResult Update(Bar item);
{
return base.Update(item);
}
}
PS
if you are still not satisfied, look at the beginning of my answer and forget about the generic repositories. Use the custom ones as the most proffesional developes do.

C# OOP : Using interface with type parameters in base concrete class

I hope the title is descriptive of the problem, I had trouble phrasing the problem I am trying to solve.
I'm using .NET Core 2.1
I've recently started at a C# shop after doing Python for the last 5 years so my strongly typed oop is a bit rusty. Here is what I have and what I'm trying to do:
I a base repository interface that defines basic CRUD functionality for database entities:
public interface IRepository<TEntity, TPrimaryKey> where TEntity : class
{
TEntity FindById(TPrimaryKey id)
void Create(TEntity entity);
void Delete (TEntity entity);
}
I inherit from this interface to define the interface that my repository class implements:
interface IProductRepository : IRepository<Product, int>
{
void SomeProductRepoMethod(int someParam);
}
Then I implement all interface methods in my concrete class:
public class ProductRepository : IProductRepository
{
public Product FindById(int id)
{
// lookup
}
public void Create(Product product)
{
// save
}
public void SomeProductRepoMethod(int someParam)
{
// do product repository specific stuff
}
....
}
Now, what I want to do is fairly straightforward. I want to add a overload of Create on IRepository that takes an IEnumerable of TEntity :
public interface IRepository<TEntity, TPrimaryKey> where TEntity : class
...
void Create(IEnumerable<TEntity> entities);
...
But I'd like to define the implementation of this overload once:
So I was thinking I could make a abstract base repository class to put the above implementation. The problem I am facing is I'm not sure how or even if I could do this cleanly with the modelI have now. I tried to make a base class that implements IRepository, but that would mean
passing type params to the base class and on to the interface:
public abstract class BaseRepository<TEntity, TPrimaryKey> : IRepository<TEntity, TPrimaryKey>
{
public abstract TEntity FindById(TPrimaryKey id);
public abstract void Create(TEntity entity);
public abstract void Delete(TEntity entity);
public void Create(IEnumerable<TEntity> entities)
{
foreach(TEntity entity in entities)
{
Create(entity);
}
}
}
Then in my concrete repository:
public class ProductRepository : BaseRepository<Product, int>, IProductRepository
{
public override Product FindById(int id)
{
// lookup
}
public override void Create(Product product)
{
// save
}
public void SomeProductRepoMethod(int someParam)
{
// do product repository specific stuff
}
....
}
This doesn't feel quiet right to me since I am passing the same type params in both IProductRepository and ProductRepository. I feel like
I'm close but not there and I'm not sure what the best practice approach here would be. If anyone could suggest an approach I would really
appreciate the feedback. Apologies for the length of the post but I felt I needed to clearly describe what I was trying to do. Thanks!
Having the same type parameters in an interface and an abstract class is not that big of a deal. Using your abstract class solution is okay, unless your ProductRepository needs to inherit from some other class.
Actually, with your abstract class, your IRepository interface doesn't need to exist anymore. Just handle everything with BaseRepository!
Another solution to this problem is an extension method. In a static class, you can write this:
public static void Create<TEntity, TPrimaryKey>(this IRepository<TEntity, TPrimaryKey> repo, IEnumerable<TEntity> entities) where TEntity : class {
// do your foreach loop here
}
Now you can call this method on any IRepository instance just like this:
repository.Create(...);
Here's the way I'd do it. I'd break the inheritance between IRepository and IProductRepository:
Here are your interfaces:
public interface IRepository<TEntity, TPrimaryKey> where TEntity : class
{
TEntity FindById(TPrimaryKey id);
void Create(TEntity entity);
void Delete(TEntity entity);
void Create(IEnumerable<TEntity> entities);
}
internal interface IProductRepository
{
void SomeProductRepoMethod(int someParam);
}
Then let your base class inherit IRepository as you've done:
base class:
public abstract class BaseRepository<TEntity, TPrimaryKey> :
IRepository<TEntity, TPrimaryKey> where TEntity : class
{
public abstract TEntity FindById(TPrimaryKey id);
public abstract void Create(TEntity entity);
public abstract void Delete(TEntity entity);
public void Create(IEnumerable<TEntity> entities)
{
foreach (TEntity entity in entities)
{
Create(entity);
}
}
}
and then you derive your base class and also implement your IProductRepository:
public class ProductRepository : BaseRepository<Product, int>, IProductRepository
{
public override Product FindById(int id)
{
// find
}
public override void Create(Product product)
{
// save
}
public void SomeProductRepoMethod(int someParam)
{
// do product repository specific stuff
}
public override void Delete(Product entity)
{
// delete
}
}
I think your derived class' specificity to being a Product repository is an implementation detail on BaseRepository.

Why is a generic repository considered an anti-pattern? [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 7 years ago.
Improve this question
it seems to me that a lot of specialised repository classes share similar characteristics, and it would make sense to have these classes implement an interface that outlines these characteristics, creating a generic repository
to illustrate my point, say we have this code
public class IEntity
{
public int Id;
}
public interface IRepository<T> where T: IEntity
{
IEnumerable<T> List { get; }
void Add(T entity);
void Delete(T entity);
void Update(T entity);
T FindById(int Id);
}
[Table("Author")]
public partial class Author : IEntity
{
public int Id { get; set; }
[Required]
public string authorname { get; set; }
}
and then we go onto implement these interfaces to create our specific repositories
public class AuthorRepository : IRepository<Author>
{
Model1 _authorContext;
public AuthorRepository()
{
_authorContext = new Model1();
}
public IEnumerable<Author> List
{
get
{
return _authorContext.Authors;
}
}
public void Add(Author entity)
{
_authorContext.Authors.Add(entity);
_authorContext.SaveChanges();
}
public void Delete(Author entity)
{
_authorContext.Authors.Remove(entity);
_authorContext.SaveChanges();
}
public void Update(Author entity)
{
_authorContext.Entry(entity).State = System.Data.Entity.EntityState.Modified;
_authorContext.SaveChanges();
}
public Author FindById(int Id)
{
var result = (from r in _authorContext.Authors where r.Id == Id select r).FirstOrDefault();
return result;
}
}
before i implemented this, i went out a did a bit of research about whether it was a good idea or not, and all the information i could find were statements calling it an anti-pattern but without explaining why.
Why is a generic repository considered an anti-pattern?

Code Contracts for composed interfaces

I'm working with Microsoft Code Contracts for a little while now and today I stumbled upon an awkward case. My question is - is there an elegant way to resolve this situation?
Let's assume I've got a simple trait interface for a repository which looks like this:
[ContractClass(typeof(CanAddContract)]
public interface ICanAdd {
void Add(object entity);
}
The contract for this, as denoted in the attribute, looks like this:
[ContractClassFor(typeof(ICanAdd))]
internal abstract class CanAddContract {
public void Add(object entity) {
Contract.Requires(object != null); // guard against null argument
}
}
So, now we've got a similar trait for entity deletion
[ContractClass(typeof(CanDeleteContract))]
public interface ICanDelete {
void Delete(object entity);
}
...and the contract...
[ContractClassFor(typeof(ICanDelete))]
internal abstract class CanDeleteContract {
public void Delete(object entity) {
Contract.Requires(entity != null); // guard against null argument
}
}
Nothing wrong about that. But since the interfaces denote repository traits, they are being used to compose a repository interface:
public interface IEntityStore : ICanAdd, ICanDelete {
void SomeOtherMethodThatNeedsAContract();
}
Now what? When I want to create a contract class for this interface, I have to reimplement both contract classes stated above again, since multi-inheritance isn't allowed in C#. This leaves me in a situation where I have to duplicate code for a CONTRACT. Think about that - this seems wrong to me in every possible case.
What could I do about it?
The CodeContracts compile-time rewriter will automatically discover and use the contracts for all base interfaces.
For your specific example (note how you do NOT need to repeat any of the base interfaces' contracts, and yet they still work):
using System;
using System.Diagnostics.Contracts;
namespace Demo
{
[ContractClass(typeof(CanAddContract))]
public interface ICanAdd
{
void Add(object entity);
}
[ContractClassFor(typeof (ICanAdd))]
internal abstract class CanAddContract: ICanAdd
{
public void Add(object entity)
{
Contract.Requires(entity != null);
}
}
[ContractClass(typeof(CanDeleteContract))]
public interface ICanDelete
{
void Delete(object entity);
}
[ContractClassFor(typeof(ICanDelete))]
internal abstract class CanDeleteContract: ICanDelete
{
public void Delete(object entity)
{
Contract.Requires(entity != null);
}
}
[ContractClass(typeof(EntityStoreContract))]
public interface IEntityStore: ICanAdd, ICanDelete
{
void SomeOtherMethodThatNeedsAContract(object entity);
}
// Note how we only specify the additional contract for SomeOtherMethodThatNeedsAContract().
// We do NOT need to repeat the contracts for ICanAdd and ICanDelete.
// These contracts are automatically inferred from the ICanAdd and ICanDelete contracts.
[ContractClassFor(typeof(IEntityStore))]
internal abstract class EntityStoreContract: IEntityStore
{
public void SomeOtherMethodThatNeedsAContract(object entity)
{
Contract.Requires(entity != null);
}
public abstract void Add(object entity);
public abstract void Delete(object entity);
}
public sealed class EntityStore: IEntityStore
{
public void Add(object entity)
{
}
public void Delete(object entity)
{
}
public void SomeOtherMethodThatNeedsAContract(object entity)
{
}
}
public static class Program
{
private static void Main()
{
var entityStore = new EntityStore();
entityStore.Add(null); // This will correctly give a code contracts exception.
}
}
}

Entity Framework with a layered web application

I know that this question seems to be already made here, but I have specific doubts, mainly in database-first usage and lack of code-example in replied questions.
I have these layers: Core, Data and UI (asp.net mvc).
I have these tables in MSSQL: Person and Contact.
Question 1: In data layer, EDMX generates Person and Data POCO. Where I write methods like SearchPersonByCity() ? Do I need to create another Person class in the same data layer, just for writting data CRUD? How I make this? Please make an example (classes, namespaces, etc.. not necessary the whole actual code)
Question 2: How do I transpose these data between data-layer and core (domain models)? Where do I need to create the same SearchPersonByCity() in core (domain) class? Maybe create another Person class in core-layer just for these data-acess methods?
Please give me some code example, and how big companies do in real life, because it seems to be so dumb and a lot of code to mantain and problaby I'm getting something wrong.
I'm not lazy, and I read hundreds pages of Entity Framework books, questions here, and I can't figure out how to do this in code.
In my opinion I would use the repository pattern in your case, so first you have a IRepository class defined:
public interface IRepository<T> where T :
{
void Add(T entity);
void Update(T entity);
void Delete(T entity);
void Delete(Expression<Func<T, bool>> where);
T GetById(long id);
T GetById(string id);
T Get(Expression<Func<T, bool>> where);
}
And an abstract base RepositoryBase class:
public abstract class RepositoryBase<T> where T : class
{
private PersonDBEntities dataContext;
private readonly IDbSet<T> dbset;
protected RepositoryBase(IDatabaseFactory databaseFactory)
{
DatabaseFactory = databaseFactory;
dbset = DataContext.Set<T>();
}
protected IDatabaseFactory DatabaseFactory
{
get;
private set;
}
protected PersonDBEntities DataContext
{
get { return dataContext ?? (dataContext = DatabaseFactory.Get()); }
}
public virtual void Add(T entity)
{
dbset.Add(entity);
}
public virtual void Update(T entity)
{
dbset.Attach(entity);
dataContext.Entry(entity).State = EntityState.Modified;
}
public virtual void Delete(T entity)
{
dbset.Remove(entity);
}
public virtual void Delete(Expression<Func<T, bool>> where)
{
IEnumerable<T> objects = dbset.Where<T>(where).AsEnumerable();
foreach (T obj in objects)
dbset.Remove(obj);
}
public virtual T GetById(long id)
{
return dbset.Find(id);
}
public virtual T GetById(string id)
{
return dbset.Find(id);
}
public virtual IEnumerable<T> GetAll()
{
return dbset.ToList();
}
//You can return IQueryable if you want to build your expression true later on...
public virtual IEnumerable<T> Get(Expression<Func<T, bool>> where)
{
return dbset.Where(where).ToList();
}
}
And your PersonRepository class:
public class PersonRepository: RepositoryBase<Person>, IPersonRepository
{
public PersonRepository(IDatabaseFactory databaseFactory)
: base(databaseFactory)
{
}
}
public interface IPersonRepository : IRepository<Person> // Person will be your POCO class
{
}
Next step is on your service layer, you will define and implement that actual SearchPersonByCity() method:
public class PersonService : IPersonService
{
private readonly IPersonRepository personRepository;
private readonly IUnitOfWork unitOfWork;
public PersonService(IPersonRepository personRepository, IUnitOfWork unitOfWork)
{
this.personRepository = personRepository;
this.unitOfWork = unitOfWork;
}
public IEnumerable<Person> SearchPersonByCity(string city)
{
var persons = personRepository.Get(p => p.City == city);
return persons;
}
}

Categories