All I am trying to find out the correct definition of the repository pattern.
My original understanding was this (extremely dumbed down)
Separate your Business Objects from your Data Objects
Standardize access methods in data access layer.
I have really seen 2 different implementation, and there are no formal examples online, the ones i have seen are tucked away in books.
Implementation 1 :
public Interface IRepository<T>{
List<T> GetAll();
void Create(T p);
void Update(T p);
}
public interface IProductRepository: IRepository<Product> {
//Extension methods if needed
List<Product> GetProductsByCustomerID();
}
Implementation 2 :
public interface IProductRepository {
List<Product> GetAllProducts();
void CreateProduct(Product p);
void UpdateProduct(Product p);
List<Product> GetProductsByCustomerID();
}
Notice the first is generic Get/Update/GetAll, etc, the second is more of what I would define "DAO" like.
Both share an extraction from your data entities. Which I like, but i can do the same with a simple DAO. However the second piece standardize access operations I see value in, if you implement this enterprise wide people would easily know the set of access methods for your repository.
Am I wrong to assume that the standardization of access to data is an integral piece of this pattern ? If both are correct why would one choose to do implementation 2?
Rhino has a good article on implementation 1, and of course MS has a vague definition and an example of implementation 2 is here.
I second the Fowler quote cited by oded. I want to point out that he said "collection-like" interface. How you implement the collection like interface is certainly up to you, but neither can nor should you try to hide the fact it represents a remote datasource. It therefore differs significantly from an in-memory collection, which does not need to flush changes to a remote data store. The change tracking mechanism of your ORM or your roll-your-own solution determines how transparent this can be made to the caller. Deletes usually need to be marked explicitly, inserts are discoverable (persistence by reachability) and updates sometimes need to be marked explicitly too. Combine this with the complicated dependencies of your aggregate roots and you'll see that's not very collection like.
There is no such thing as "the cannonical repository implementation".
There is a constant battle going on between the advocators of a generic repository base class and those who prefer implementing each repository on its own. While the generic implementation is appealing in simple scenarios, you will very often find it to be a very leaky abstraction. For example some of your aggregates may only be soft-deleted (cistomizable via virtual method overrides) while others may not support a delete operation at all.
Make sure you understand the implications of each approach before deciding which route to take. Greg Young has a good post on the merits of generic repositories.
https://web.archive.org/web/20090204223739/http://codebetter.com/blogs/gregyoung/archive/2009/01/16/ddd-the-generic-repository.aspx
From Martin Fowler "Patterns of Enterprise Application Architecture", the definition of the Repository Pattern is:
Mediates between the domain and data mapping layers using a collection-like interface for accessing domain objects.
So, both approaches are correct.
I am a great fan of the generic repository pattern but I think you should strongly consider not directly inheriting from the interface as it can become a very large limitation especially since many times the code for the generic interface will be the same that it could be defined in an abstract base class that you will no longer be able to have more than 1 generic repository inside a class.
I recommend having your IProductRepository implementer access the generic IRepository<Product> through delegation and inject that in through the constructor so you can compose your class of possibly many IRepositories and group them behind a single interface in a way that makes sense.
I wrote a blog on this topic while it specifically references NHibernate this pattern can be applied to any type of repository: Creating a common generic and extensible NHiberate Repository version 2
With the introduction of LINQ in .NET, a generic repository pattern becomes much easier to realize:
public interface IRepository<T> : IQueryable<T>
{
void Add(T item);
void Remove(T item);
}
To qualify as a repository, it merely needs to be able to access data in the underlying store (easily provided by IQueryable) and modify the contained data.
You can provide extensions to the base interface to provide hooks for more entity-specific behaviour (such as wiring into a stored procedure call for a SQL-based repository), but the majority of operations can be completed by the simple interface.
In addition to your generic repository interface (implementation 1) and your variation on the role-specific repository (implementation 2) you can also consider a generic method repository:
public interface IRepository
{
void Save<ENTITY>(ENTITY entity) where ENTITY : DomainEntity;
ENTITY Load<ENTITY>(Guid id) where ENTITY : DomainEntity;
IQueryable<ENTITY> Query<ENTITY>() where ENTITY : DomainEntity;
IQueryable<ENTITY> Query<ENTITY>(IDomainQuery<ENTITY> whereQuery)
where ENTITY : DomainEntity;
}
This third version comes from this blogpost by Jimmy Bogard, where he also expresses preference for the generic repository interface.
I usually follow that with a generic repository baseclass which implements this interface; that way, I only have to implement the stuff that is different for each domain entity.
I usually use the generic repository with composition instead of inheritance. That gives me the advantage of a generic implementation, with the control of which methods to expose.
Something like this:
public Interface IRepository<T>{
List<T> GetAll();
void Create(T p);
void Update(T p);
}
public interface IProductRepository {
//Extension methods if needed
List<Product> GetProductsByCustomerID();
List<T> GetAll();
void Create(T p);
//Let assume here you should not be able to update the products
}
public ProductRepository : IProductRepository {
private IRepository _repository;
public ProductRepository(IRepository repository) {
this._repository = repository;
}
List<T> GetAll()
{
_repository.GetAll();
}
void Create(T p)
{
_repository.Create(p);
}
List<Product> GetProductsByCustomerID()
{
//..implementation goes here
}
}
The repository pattern is one of the most used pattern in software development. The are many post that can be marked as answer to your question.
Something that i like to highlight is the fact that a good repository implementation will be improved if you use IoC (Autofac, Windsor, etc...). I have been playing long time ago with some ADO.NET based frameworks (LinqToSql, EF) and NHibernate. You always can have benefits from a generic implementation if you use IoC.
You can define interfaces for your specific repositories and resolve when you really need some specific actions.
Related
So I had a discussion with a coworker on implementing contract from a Base class to an interface.
We have the following structure with DDD, Api -> Application -> Domain -> Infrastructure.
In the infrastructure we use EF Core.
The following code example
Application
public interface IOrderRepository
{
IUnitOfWork UnitOfWork { get; }
Task AddOrderAsync(Order order);
}
Infrasctucture
public class OrderRepository : BaseRepository<Order, DbContext>, IOrderRepository
{
public OrderRepository(DbContext ctx) : base(ctx) { }
public async Task AddOrderAsync(Order order)
{
try
{
await AddAsync(order);
}
catch (Exception ex)
{
Log.Error($"Exception: {ex}");
throw ex;
}
}
/*
*
* Some other db methods
*
*/
}
public abstract class BaseRepository<T, U> where T : class where U : BaseDbContext, IUnitOfWork
{
protected readonly U _context;
public IUnitOfWork UnitOfWork
{
get
{
return _context;
}
}
public BaseRepository(U context)
{
_context = context;
}
protected virtual async Task AddAsync(T entity)
{
await _context.Set<T>().AddAsync(entity);
}
}
So I am arguing for, instead of implementing AddNAMEAsync methods in every repository to make AddAsync public virtual in the base class, and in corresponding interfaces and making use of the base class implementation. This way we also still have the possibility to orderride AddAsync if needed and also minimize unneccesary "duplicate code" in repositories.
My coworker on the other hand thinks that this will make the name too generic and when calling the repository you will not know which entity you are adding to the context by just reading the code. And aslo arguing on that we should not expose base class methods in interfaces, but that it instead should only be Parent -> Child exposure.
We are using SOLID principles and each handler only handles one entity/domain aggregate, we also have very clear naming on our variables/objects so you can easily see what you are adding to the context in the repository name as well as in the domain model
You can use AddAsync(T entity) method in BaseRepository, this will be provided reusable code for all your entities but this is already been implemented by Entity Framework Core. Do you really need to implement this structure again?
EF Core already provides the DbSet as base repository and DbSet<Order> as your order repository. Also provides DbContext as a unit of work implementation.
You don't need to create your generic base repository, repository, and unit of work classes if you don't use any other ORM tool or approach of persistence with EF Core. EF Core already provides these patterns as encapsulated.
What will encapsulating the classes and methods provided by EF Core solve in this way?
What are the differences between EF Core's DbSet and your BaseRepository?
See this sample project
In terms of naming you can, from my point-of-view, safely use "AddAsync()". The more important thing is that the client working with the repository uses a type of IOrderRepository. In this case, when looking at AddOrderAsync() the Order part could be seen as redundant in terms of naming because, first, you are calling it on a type that already indicates that everything is about orders, and second, you are passing an object of type Order which again indicates what you are going to add.
What you could still do is to make explicit that the generic methods are also part of an generic interface (e.g. IRepository) which IOrderRepository could extend. If you want to derive your infrastructure OrderRepository from a base class or if you want to pass it in some other object in terms of favouring composition over inheritance (e.g. a DbContext) is an implementation detail.
You can see an illustration of what I'm referring to here in the microservices reference application of Microsoft (eshopOnContainers).
I think you are right about implementing the AddAsync() method in a base class and inherit other classes from it. Because, when you want to use AddAsync() you will first inject the related class and then use it. (It will provide reusable code-base for you)
public class MyClass
{
private readonly OrderService _orderService;
//..
await _orderService.AddAsync(...);
}
There is no problem in terms of naming in this type of use, because the relevant service and what it will do are very clear.
Btw, CreateAsync or InsertAsync could be a better naming in my opinion to demonstrate database operation.
I have two repositories AlbumRepository with interface IAlbumRepository and CachedAlbumRepository with interface IAlbumRepository which has constructor interface IAlbumRepository. I need inject with Ninject ICachedAlbumRepository with CachedAlbumRepository and constructor with AlbumRepository.
How to achieve it with Ninject?
Same approach with structure map
x.For<IAlbumRepository>().Use<CachedAlbumRepository>()
.Ctor<IAlbumRepository>().Is<EfAlbumRepository>();
public class CachedAlbumRepository : IAlbumRepository
{
private readonly IAlbumRepository _albumRepository;
public CachedAlbumRepository(IAlbumRepository albumRepository)
{
_albumRepository = albumRepository;
}
private static readonly object CacheLockObject = new object();
public IEnumerable<Album> GetTopSellingAlbums(int count)
{
string cacheKey = "TopSellingAlbums-" + count;
var result = HttpRuntime.Cache[cacheKey] as List<Album>;
if (result == null)
{
lock (CacheLockObject)
{
result = HttpRuntime.Cache[cacheKey] as List<Album>;
if (result == null)
{
result = _albumRepository.GetTopSellingAlbums(count).ToList();
HttpRuntime.Cache.Insert(cacheKey, result, null,
DateTime.Now.AddSeconds(60), TimeSpan.Zero);
}
}
}
return result;
}
}
You need to create 2 bindings - one that says inject CachedAlbumRepository into anything that needs an IAlbumRepository and another that says inject a normal AlbumRepository into CachedAlbumRepository. These bindings should do that:
Bind<IAlbumRepository>()
.To<CachedAlbumRepository>();
Bind<IAlbumRepository>()
.To<AlbumRepository>()
.WhenInjectedInto<CachedAlbumRepository>();
I can't answer the question for you, but I have some feedback for you.
Your application design misses a great opportunity. It misses the opportunity to be and stay maintainable. Since you defined a decorator (the CachedAlbumRepository is a decorator), you will probably start writing decorators for other repositories as well. I imagine you having a decorator for your IArtistRepository, IRecordLabelRepository, etc.
Having to implement these duplicate repositories is a violation of the DRY principle. But the violation of DRY is actually caused by a violation some other principles. Your design is violating some of the SOLID principles, namely:
Your design violates the Single Responsibility Principle, because the query methods that you'll place inside your repository (such as the GetTopSellingAlbums method) are not very cohesive. In other words, your repository classes will get big and will do too much and start to get hard to read, hard to test, hard to change, and hard to maintain.
Your design violates the Open/closed principle, since you will have to alter a repository every time you add a new query to the system. This means changing the interface, changing the decorator, changing the real implementation, and changing every fake implementation there exists in the system.
Your design violates the Interface Segregation Principle, because your repository interfaces will get wide (will have many methods) and consumers of those interfaces are forced to depend on methods that they don’t use. This makes it harder and harder to implement decorators and write fake objects.
The solution to this problem is to hide all repositories behind one single generic abstraction:
public interface IRepository<TEntity>
{
void Save(TEntity entity);
TEntity Get(Guid id);
}
Since this is a generic interface, it doesn't give you any room to add any entity-specific query methods, and this is good. It is good, because the IRepository<T> will be narrow and stable. This makes it really easy to add decorators to it (if you still need to add decorators here).
The trick is to prevent adding query methods to this interface (and don't inherit new interfaces from this interface), but to give each query in the system its own class. Or in fact, two classes. One class with the definition of the data, and one class that knows how to execute that query. And last but not least, you can hide each class behind the same generic abstraction for queries (just as we have one generic abstraction over repositories). And when you do this, you just have to define one single caching decorator that you can apply to any subset of queries in the system.
You can read in detail about this design here. This might seem a bit abstraction at first, but I promise you, when you get the hang of this, there's no way you're ever getting back to your old design.
I'm a beginner to ASP.net MVC. And liking it a lot more than WebForms.
So i decided to start a project which contains about 6 tables:
Gallery
Admins
Sessions
SessionImages
Offers
Info
I've created two projects : FP.WebUI and FP.Domain.
Inside my domain project i've created 3 folders Abstract, Concrete and Entities.
Inside Abstract folder there are 6 interfaces IGallery, ISessions.. etc. Each interface has something like this :
namespace FP.Domain.Abstract
{
public interface IGallery
{
IQueryable<Gallery> Gallery { get; }
}
}
And inside Concrete folder there are another 7 classes : EFDbGallery, EFDbSessions... and EFDbContext which inherites from DbContext class.
Each class of the above (except EFDbContext), implements each of the corresponding interface.
Now when i thought about it i found that i could make one interface which defines all the entities and only one class inside Concrete folder which implements that interface.
I really don't know what's better :
6 interfaces, 6 classes for each entity.
OR
1 interface, 1 class which returns all entities.
You seem to have stumbled upon the Repository pattern. The typical architectural decision is to create an interface
interface IRepository
{
IQueryable<Gallery> Query { get; }
}
Then have your ORM class implement the repository interface.
class MyDbContext : DbContext , IRepository
{
}
Now at this point, to answer your question, should I use 6 classes and 6 interfaces or 1 class and 1 interface the answer is categorically NO!
The typical pattern calls for a GENERIC interface (so in effect you have 6 interfaces, but a single interface source, if you need extra calls you can extend the generic).
//Actually this implementation is edging on
//Unit Of Work
interface IRepository<T>
{
IQueryable<T> Query { get; }
void Insert(T item);
void SaveChanges();
}
Then your EfContext exposes all of the interfaces. The reason being is that your controllers only typically need a single interface to work, and this makes mock/fake testing MUCH MUCH easier on your controllers (you don't need to create implementations of unused methods like an InfoQuery for a GalleryControllerTest).
If you find you need to have domain specific code for any interface you could extend the IRepository interface.
interface IGalleryRepository : IRepository<Gallery>
{
void SomeSpecialOperation(Gallery item);
}
Finally, implementation of this pattern will make life much easier if/when you start introducing Inversion of Control.
PS I typically refactor out the ACTUAL EF code (ie the concrete Repository) into a separate assembly, this is simply in case you ever decide to drop EF from your project.
I would use 7 classes because they will have different responsibilities.
.
You might feel this is homework, for that I am sorry. I have searched but couldn't find a proper answer.
So my question is:
I have several classes and each class has a method to save. So I created a separate class for database handling.
namespace HospitalMgt.Data
{
public static class DBConnection
{
public static string constr = "Data Source=ABD;Initial Catalog=HospitalMgt;User Id=sa;Password=123";
public static SqlConnection con;
// public static SqlCommand com;
public static SqlConnection OpenConnection()
{
con= new SqlConnection(constr);
con.Open();
return con;
}
}
}
However, I don't think it's suitable to implement all the classes with a DBConnection class.
My question :
What design pattern is suited to overcome this problem?
Is it good practise to create DBConnection as class? (Or should it be an Interface)
I found a few articles about DA layers using the Factory method, but according to my knowledge, that pattern does not suit my situation.
Normally, if I can't use any existing framework, I use both the Repository and Active patterns.
For simplicity, you could use only the Repository pattern. I normally define it like this:
public interface IEntity<T> { }
// Define a generic repository interface
public interface IRepository<TKey, TEntity>
where TEntity : IEntity<TKey>
{
void Add(TEntity entity);
void AddRange(IEnumerable<TEntity> entities);
IEntity<TKey> Get(TKey key);
IEnumerable<TEntity> GetRange(IEnumerable<TKey> keys);
IEnumerable<TEntity> GetAll();
// ..., Update, Delete methods
}
// Create an abstract class that will encapsulate the generic code
public abstract class Repository<TKey, TEntity> : IRepository<TKey, TEntity>
where TEntity : IEntity<TKey>
{
protected Repository(/*parameter you may need to implement the generic methods, like a ConnectionFactory, table name, entity type for casts, etc */) { }
public override void Insert(IEntity<TKey> entity)
{
// do the insert, treat exceptions accordingly and encapsulate them in your own and more concise Exceptions, etc
}
// ...
}
// Create the entities classes, one for each table, that will represent a row of that table
public class Car : IEntity<string> {/* Properties */}
// Create a specific repository for each table
// If the table have a composed key, just create a class representing it
public class CarRepository : Repository<string, Car>
{
public CarRepository() {/* pass the base parameters */}
// offer here your specific operations to this table entity
public IEnumerable<Car> GetByOwner(PersonKey ownerKey)
{
// do stuff
}
}
Obviously, when doing your own implementations, you must take into account thread safety making good using of transactions, specially across diferent entity repositories.
// simple example
ITransaction t = TransactionFactory.GetNewTransaction();
t.begin();
try{
// create person entity
personRepository.Add(person, t);
// create cars assigned to person
carRepository.AddRange(cars, t);
t.commit();
}catch(Exception){
t.rollback();
}
Just be sure that you really want to create your own DAL since it can end beeing extremelly complex, specially trying to develop the most generic solution.
First of all, I would like to recommend you the article Design Patterns for Data Persistence by Jeremy Miller.
There are some data access layer patterns:
Active record pattern (wiki, Detailed info).
Repository pattern (Detailed info).
I suggest using an ORM, Entity Framework or NHibernate will do nicely. Then you do not have to worry about a db context or create SQL statements.
Its too old but just came around this question and could not resist to post my thoughts.
I found Repository with UnitOfWork with some descent ORM is good approach. This minimizes most of the issues.
The UoW mentioned in above link can be injected in Repository. That increases the flexibility of usage. Also, all DB Communication code is centralized at one place. The example is not complete but a startup point.
Repository pattern mentioned in above link is actually a generic base class. You can create new class for each of your concrete Repository that derives from it.
Generic repository is considered an anti pattern; there are lot many articles on internet that explains it.
Why generic repository is anti-pattern?
A repository is a part of the domain being modeled, and that domain is not generic.
Not every entity can be deleted.
Not every entity can be added
Not every entity has a repository.
Queries vary wildly; the repository API becomes as unique as the entity itself.
For GetById(), identifier types may be different.
Updating specific fields (DML) not possible.
Generic query mechanism is the responsibility of an ORM.
Most of the ORMs expose an implementation that closely resemble with Generic Repository.
Repositories should be implementing the SPECIFIC queries for entities by using the generic query mechanism exposed by ORM.
Working with composite keys is not possible.
It leaks DAL logic in Services anyway.
Predicate criteria if you accept as parameter needs to be provided from Service layer. If this is ORM specific class, it leaks ORM into Services.
I suggest you read these (1, 2, 3, 4, 5) articles explaining why generic repository is an anit-pattern.
Solution:
Write an abstract Generic Repository that is wrapped by a concrete repository. That way you can control the public interface but still have the advantage of code-reuse that comes from generic repository.
Use a Generic Repository but do use composition instead of inheritance and do not expose it to the domain as a contract.
In any case, do not expose Generic Repository to calling code. Also, do not expose IQueryable from concrete repositories.
I suggest you to use a RepositoryBase for all this common operations. If you decide to use an ORM for data access it's good to think in a implementation of repositories based on a Generic Type repository.
Here is a good article about it:
http://lostechies.com/jimmybogard/2009/09/03/ddd-repository-implementation-patterns/
Having a generic repository like
public class Repository<T>
where T: Entity<T>
{
/*anything else*/
}
should concrete repositories per agregation root like
class ProductRepository : Repository<Product>
{
}
class CategoryRepository : Repository<Category>
{
}
be created?
Also how do I use DI (Ninject) with generic implementation of repository.
Samples are apreciated!
Thanks!
I see a lot of misuse of generics in the questions in SO and while it does not necessarily refer to your question (although it will help to clarify), I think once for all write a summary here.
Generics is a typeless reuse of the behaviour (almost, since you can limit the types using restrictions). If a behaviour is shared by all types (or those limited to restrictions) you use the generics.
However if implementation of each generic type needs to be individually implemented, then using generics does not help and is reduced to a decoration - and for me it is bad design.
OK, let's have an example:
interface IConverter<T1, T2>
{
T1 Convert(T2 t2);
}
This looks like a good generics (converting one type to another), but I have to implement all such combinations of types as different converters. And a IConverter<Apple, Orange> does not make any sense. Hence generics here is misleading and BAD.
Now going back to repositories. There are 100s of articles on this particular issue (lots of controversies) but this is personal my take:
Usually it is not recommended to use generic repositories. However, in my personal experience I use generic repository to implement common stuff (implemented by a base repo) and then use individual ones if there is any additional:
interface IRepository<T>
{
T GetById(int id);
IEnumerable<T> GetAll();
void Save(T t);
}
class BaseRepository<T> : IRepository<T>
{
... // implement common methods
}
interface IProductRepository : IRepository<T>
{
IEnumerable<T> GetTop5BestSellingProducts();
}
class ProductRepository : BaseRepository<T>, IProductRepository
{
... // implement important methods
}
NOTE
Some believe repository must allow for criteria to be passed to the repository (Eric Evans DDD book) but I again do not feel I have to agree to that. I prefer a domain-significant declaration on the repository (e.g. GetTopFiveBestSellingProducts or GetTopBestSellingProducts) unless there are 100s of such like in a report writer which is only 1% of cases.
Second question:
I do not use Ninject but for any DI, here is how you do it
// PSEUDOCODE !!!
container.Register<IProductRepository , ProductRepository>();
depending on DI framework, it can be slightly different.