Why is a generic repository considered an anti-pattern? [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 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?

Related

Minimize Boilerplate [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed 3 months ago.
Improve this question
I need to implement some classes that inherit from the interface below. Many of the implementations differ only in the value returned by P. How can I minimize the number of lines of code?
public class A // I cannot change it
{
public A(string _) { }
//...
}
public interface I // I cannot change it
{
A P { get; }
void f();
//...
}
public class B : I // many similar classes: they differ by signature, only
{
public static A StaticP => new A("signature");
public A P => StaticP;
public void f()
{
//...
}
//...
}
You can move the code from f(), etc. into an abstract base class. Something like this:
public abstract class BaseI : I
{
public abstract A P { get; }
public void f()
{
//...
}
//...
}
public class B : BaseI
{
public static A StaticP => new A("signature");
public override A P => StaticP;
}

What is the benefit of having an interface for a "model" class in .NET? [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 3 years ago.
Improve this question
What is the purpose of having an interface for a model class when there is no methods for this class and its not inheriting anywhere other than Event class? Please read the question properly. It's about model class and interface not about interface inheritance for a normal class.
public interface IEvent
{
int EventID{get;set;}
string EventName{get;set;}
}
public class Event:IEvent
{
public Event(int eventID, string eventName)
{
this.EventID = eventID;
this.EventName = eventName;
}
public int EventID { get; set; }
public string EventName { get; set; }
}
Interfaces are useful for establishing a contract - implementors MUST match the contact.
Interfaces are also useful for Mocking in unit tests, or DI/IoC.
Its possible whoever created your interface was using it for one of these two reasons...
One of the advantages is Multiple inheritances ex.
public interface IEvent
{
int event Id {get;set}
string EventName{get;set}
}
public interface IEventDES
{
string event Description{get;set}
}
public class Event:IEvent, IEventDES
{
public Event(int eventID,string eventName, string Description)
{
this.EventID=eventID;
this.EventName=eventName;
this.Description= Description;
}
}

Separating interfaces and making them more generic

I have an interface to define my records\models
public interface IStockItem
{
string Code { get; set; }
string Description { get; set; }
decimal FreeStock { get; set; }
}
Is it best to put the actions into another interface?
public interface IStockExport
{
IEnumerable<IStockItem> GetAll();
IEnumerable<IStockItem> GetStockByCode(string code);
decimal GetFreeStock(string code);
}
public interface IStockImport
{
void CreateItem<IStockItem>;
}
Is there a better way to do this and make it more generic? so i can share the actions interfaces with other records\models?
The other records\models are SalesOrder, Customer, Address.
The overall idea is an Import\Export program, that will create\export sales orders in a number of different accounts packages via an API.
This is a common pattern, called the Repository Pattern.
If you want to go down this route, you should create a base interface, Repository<T>, for example:
public interface IRepository<T>
{
void Insert(T entity);
void Delete(T entity);
IEnumerable<T> SearchFor(Func<T, bool> predicate);
IEnumerable<T> GetAll();
T GetById(int id);
}
You would make your IStockItem implement an IEntity interface so that it can provide an ID for GetById(), for example:
public interface IEntity
{
int ID { get; }
}
Then you would implement the repository for a data type such as StockItem by declaring the implementing class. It might start a bit like this:
public class Repository<T> : IRepository<T> where T : class, IEntity
{
protected Table<T> DataTable;
public Repository(DataContext dataContext)
{
DataTable = dataContext.GetTable<T>();
}
...
Your code that wanted to get at a repository for a stock item might look like this:
using (var dataContext = new StockItemDataContext())
{
var StockItemRepository = new Repository<IStockItem>(dataContext);
...
This may be overkill for what you want, but it is the general approach.
For full details see this excellent blog post.
Also see this example.
Here's how you might start implementing this pattern for your case:
public interface IRepository<T>
{
void Insert(T entity);
void Delete(T entity);
IEnumerable<T> SearchFor(Func<T, bool> predicate);
IEnumerable<T> GetAll();
T GetByCode(string code);
}
public interface IStockItem: IEntity
{
string Description { get; set; }
decimal FreeStock { get; set; }
}
public sealed class StockItem: IStockItem
{
public string Code { get; set; }
public string Description { get; set; }
public decimal FreeStock { get; set; }
}
public interface IEntity
{
string Code { get; }
}
public sealed class MyLowLevelDataAccess
{
public StockItem FindStockItem(string code)
{
return null; // Call your API here.
}
public void DeleteStockItem(string code)
{
// Call your API here.
}
public void InsertStockItem(StockItem item)
{
// Call your API here.
}
public IEnumerable<StockItem> FindAllItems()
{
return FindItemsMatching(x => true);
}
public IEnumerable<StockItem> FindItemsMatching(Func<StockItem, bool> predicate)
{
return null; // Call your API here and return all items matching the predicate.
}
}
public sealed class StockRepository: IRepository<StockItem>
{
private readonly MyLowLevelDataAccess _dataAccess;
public StockRepository(MyLowLevelDataAccess dataAccess)
{
_dataAccess = dataAccess;
}
public void Insert(StockItem entity)
{
_dataAccess.InsertStockItem(entity);
}
public void Delete(StockItem entity)
{
_dataAccess.DeleteStockItem(entity.Code);
}
public IEnumerable<StockItem> SearchFor(Func<StockItem, bool> predicate)
{
return _dataAccess.FindItemsMatching(predicate);
}
public IEnumerable<StockItem> GetAll()
{
return _dataAccess.FindAllItems();
}
public StockItem GetByCode(string code)
{
return _dataAccess.FindStockItem(code);
}
}
you can use a generic interface as well:
public interface IRecordExport<T> where T : IRecordBase
{
IEnumerable<T> GetAll();
IEnumerable<T> GetOneByCode(string code);
decimal GetFree(string code);
}
public interface IRecordImport<T> where T : IRecordBase
{
void CreateItem<T>();
}
You could, but it may not be necessary. Interfaces for method-based classes are best used where you want to have polymorphism related to implementation.
In your case, it seems that what you want is to be able to share common functionality (based on the IStockExport interface) but also provide a polymorphic creation mechanism (based on IStockImport).
I would suggest that you implement an abstract base class for IStockExport which can be inherited for all the various types of IStockItem (due to common interface) and then the derived classes should implement IStockExport as each Create<IStockItem>() implementation will be different but can be used in the same way due to common behaviour (always returns IStockItem object).

Repository pattern interfaces- Best practices? [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 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.

How to do Generic Repository with Dependency Injection [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 4 years ago.
Improve this question
I have set up my generic repository as follows:
public interface IRepository<T> : IDisposable where T : Entity
{
T GetById(int id);
}
public abstract class Repository<T> : IRepository<T> where T : Entity
{
protected readonly SqlDbContext _context = new SqlDbContext();
public T GetById(int id)
{
return _context.Set<T>().Find(id);
}
}
To enable dependency injection in my MVC app i also create a Product interface since the signature differs. This is also the case for the other repositories.
public interface IProductRepository : IRepository<Product>
{
IEnumerable<Product> GetDiscountedProducts();
}
And the implementation (note the inheritance)
public class ProductRepository : Repository<Product>, IProductRepository
{
public IEnumerable<Product> GetDiscountedProducts()
{
return _context.Set<Product>().Where(x=>x)...
}
}
Finally the repository gets injected into the MVC controller using unity
public HomeController(IProductRepository repository)
{
}
Is it just me or is this inheritance chain a bit messy here? Is there any way to improve this design?
I would suggest to avoid IProductRepository for this particular case (when simply adding single and very specific method) and enhance original IRepository interface as shown below:
public interface IRepository<TEntity> : IDisposable
where TEntity : Entity
{
TEntity GetById(int id);
IEnumerable<TEntity> List(IFilterCriteria criteria);
}
and then implement
public sealed class ProductDiscountFilterCriteria : IFilterCriteria
{
// ...
}
but in such case you've to define some logic to transform criteria to an query, it could be a LINQ Expression as you'are already using LINQ. If such creteria expression approach is complex for your case - I would suggest to stick with approach you've proposed.
EDIT: IFilterCriteria is simply Query Object pattern implementation
interface IFilterCriteria<TQuery>
{
TQuery ToQuery();
}
public sealed class ProductDiscountFilterCriteria : IFilterCriteria<DynamicExpression>
{
public decimal Discount { get; private set; }
public DynamicExpression ToQuery()
{
// build expression for LINQ clause Where("Discount" > this.Discount)
}
}
OR raw SQL criteria builder:
public sealed class ProductDiscountFilterCriteria : IFilterCriteria<string>
{
public decimal Discount { get; private set; }
public string ToQuery()
{
// simplified
return "WHERE Discount < " + this.Discount;
}
}
So then you would be able to use it like:
var products = productRepository.List<Product>(
new DiscountFilterCriteria { Discount = 50 });
Dynamic LINQ examples and articles:
Dynamic LINQ (Part 1: Using the LINQ Dynamic Query Library)
Dynamic LINQ (A little more dynamic)
Dynamic LINQ Part 2 (Evolution)

Categories