would anybody interpret it into simple words as i'm newbie to MVC and can't understand this clearly.
A DbContext instance represents a combination of the Unit Of Work and
Repository patterns such that it can be used to query from a database
and group together changes that will then be written back to the store
as a unit. DbContext is conceptually similar to ObjectContext.
Source: http://msdn.microsoft.com/en-us/library/system.data.entity.dbcontext(v=vs.113).aspx
Unit of work and Repository are patterns for dealing with data(irrespective of if it is a database or any other storage(may be List<T> objects even)) and usually implemented while dealing with data from a database.
It only means that Entity framework internally has these two patterns implemented. To understand it better, just google for Repository Patterns and Unit of work pattern which usually go hand in hand.
If you still do not get the meaning, don't worry - until you know how to work with Entity Framework(Code First is extremely easy to understand, once you understand Linq) the understanding of pattern is not important. Refer back to the same article once you have more experience with the patterns of dealing with data. You only require a little more experience to appreciate them.
Examples of these two patterns are better described by the two interfaces:
interface IHomesRepository {
List<Home> GetAllHomes();
Home GetHomeById(int id);
void AddHome(Home home);
void UpdateHome(int id, Home home);
void DeleteHome(Home home);
}
interface IUnitOfWork : IDisposable{
IHomesRepository repository {get;}
// more repositories, if required
void Commit();
}
this is a good example to understand the unit of work and the repository pattern, i suggest you to read it until the end :
http://www.asp.net/mvc/tutorials/getting-started-with-ef-5-using-mvc-4/implementing-the-repository-and-unit-of-work-patterns-in-an-asp-net-mvc-application
Related
I'm using elastic search with my asp.net core web api. I don't quite get where the line is drawn when it comes to repository responsibility.
Here is how I have defined my implementations:
public SearchRespository: ISearchRespository<Product>
{
private ElasticClient _client
public async Task<ISearchResponse<Product>> SearchAsync(ISearchRequest request)
{
var response = _client.SearchAsync<Product>(request);
return await products;
}
. . . // others
}
In my controller:
public SearchController : Controller
{
private ISearchRespository _repo;
public SearchController(ISearchRespository repo)
{
_repo = repo;
}
public async Task<IActionResult> Search()
{
// build my search request from Request.Query
var response = await _client.SearchAsync(request);
var model = new SearchModel
{
Products = response.Documents;
Aggregations = response.Aggregations;
}
return Ok(model)
}
As it stands the repo is passing the elastic response as is. My question is have I drawn my line right? what if I just move _client to my controller or move building request and constructing model to _repo? how do you guys get your repository right?
The fact that you use Elastic Search should be an implementation detail that especially the controller shouldn't know about, so you are absolutely right in abstracting this away from the controller. I often look at the SOLID principles to get a sense whether I'm on the right track or not. If we look at the Dependency Inversion Principle, you'll see that it guides us towards a style that is also known as Ports and Adapters, which basically means that the use of an external tool is abstracted away (the port), and on the boundary of the application you implement an Adapter that connects to that third party.
So from the sense of the Dependency Inversion Principle, you're on the right track.
There is however a lot of misunderstanding of what Martin Fowler's Repository Pattern is trying to solve. The definition is as follows:
Mediates between the domain and data mapping layers using a collection-like interface for accessing domain objects.
Important to note here is that a repository is intended to be used by the domain layer.
There is however a lot of misuse of the repository pattern, because many developers start to use it as a grouping structure for queries. The repository is -as I see it- not intended for all queries in the system; but only for queries that are the domain needs. These queries support the domain in making decisions for the mutations on the system.
Most queries that your system requires however are not this kind of query. Your code is a good example, since in this case you skip the domain completely and only do a read operation.
This is something that is not suited for the repository. We can verify this by comparing it with the SOLID principles again.
Let's say we have the following repository interface:
public interface IUserRepository
{
User[] FindUsersBySearchText(string searchText, bool includeInactiveUsers);
User[] GetUsersByRoles(string[] roles);
UserInfo[] GetHighUsageUsers(int reqsPerDayThreshold);
// More methods here
}
This is a typical repository abstraction that you'll see developers write. Such abstraction is problematic from perspective of the SOLID principles, because:
The Interface Segregation Principle is violated, because the interfaces are wide (have many methods) and consumers of those interfaces are forced to depend on methods that they don’t use.
The Single Responsibility Principle is violated, because the methods in the repository implementation are not highly cohesive. The only thing that relates those methods is the fact that they belong to the same concept or entity.
The design violates the Open/Closed Principle, because almost every time a query is added to the system, an existing interface and its implementations need to be changed. Every interface has at least two implementations: one real implementation and one test implementation.
A design like this also causes a lot of pain down the road, because it becomes hard to apply cross-cutting concerns (like security, auditing, logging, caching, etc) down the line.
So this is not something the Repository pattern is intended to solve; such design is just a big SOLID violation.
The solution here is to model queries separately in your system and not use a repository at all. There are many articles written about this, and you can read my take on this here.
If I look at your design, it actually has some resemblance with the design I'm promoting here, since you seem to have a generic query method that can handle many type of queries. The query message (your ISearchRequest) seems however specific to Elastic Search. This is something you should strive to prevent, as the Dependency Inversion Principle states.
I have a class that looks like such:
public class SomeRepo : ISomeRepo
{
private IThingFactory _thingFactory;
public class SomeRepo (IThingFactory thingFactory)
{
_thingFactory = thingFactory;
}
public IThing GetThingFromDatabase(int id)
{
string thingName = /* some call that gets back some primitives */
IThing returnVal = _thingFactory.createThing(thingName);
return returnVal;
}
}
So in short, SomeRepo is a repo that is responsible for communicating with some datastore to get an IThing by Id. And IThingFactory is a simple factory that returns a new IThing given a string property.
If I am using a Dependency Injection container, should I still be relying on an IThingFactory? It seems like I am mixing the two design patterns for the sake of convenience. Is there a more elegant way to construct an IThing without the need of a factory or is what I have a good pattern to follow?
Thanks
EDIT: The DI container I am using is Ninject.
If IThink is a class that does not need more than the output from the database (so if it need nothing from the DI container) and you dont want to mock it for testing, IMHO you could create the class by calling the constructor.
Otherwise the factory pattern is the right choise in my eyes.
For NInject, there is a factory extension that makes is very easy to create factories - You have just to create the interface and the extension creates the corresponding implementation at runtime.
Dependency injection is technique to achieve loose coupling between layers, not exactly what i would describe as a design pattern.
There is nothing wrong with mixing design patterns or using multiple techniques as a general thing to state, unless you are introducing complexity where it is not needed.
So my suggestion is that you approach things by questioning your requirement and understanding the use of design patterns and then you would be able to recognize the need to use a certain pattern to make your code maintainable, extensible or whatever technical requirement you are trying to fulfill.
Questions i would ask myself:
What is the problem i am trying to tackle ?
How extensible is this logic going to be ? what are the moving parts and what are the core requirements ?
Which design pattern tackles this kind of issue ?
You also need to weigh between the complexity introduced into the code and time consumed by using certain design patterns and the benefits of using it on short as well as the long run ?
I am new to repository pattern, and I come up the following questions:
What is/are the purpose of repository pattern?
What is/are the limitation of repository pattern?
What is/are the benefits of repository pattern?
Do the methods below should be exposed in the repository pattern?
public IQueryable<T> GetQuery(){
return _objectSet;
}
public IEnumerable<T> GetAll(){
return GetQuery().AsEnumerable();
}
public IEnumerable<T> Find(Expression<Func<T, bool>> predicate){
return _objectSet.Where(predicate);
}
public T Single(Expression<Func<T, bool>> predicate){
return _objectSet.Single(predicate);
}
public T First(Expression<Func<T, bool>> predicate){
return _objectSet.First(predicate);
}
Any help please?
1.What is/are the purpose of repository pattern?
To abstract away the data source to reduce complexity. By doing so the caller do not have to have any knowledge about the data source or it's quirks. They just know that they can invoke the repository and get information from an arbitary data source.
2.What is/are the limitation of repository pattern?
It's only used to abstract away the data source.
A soft limit is that people find it hard to understand how to design the repository classes. It's common that people make the repositories to generic which in turn leaks DB implementation to the invoker, thus forcing the caller to have DB specific knowlegde (or OR/M knowledge). Those implementations are seriously flawed and provide no benefit over using OR/Ms directly.
3.What is/are the benefits of repository pattern?
Less complex code. The caller get's less complex since they only have to invoke a method in the repository to fetch and store information in the data source. And the Data Access Layer get's less complex sinvce the repositories only focuses on retreiving and storing information.
4.Do the methods below should be exposed in the repository pattern?
No. IQueryable<T> leaks DB specific information. You need for instance to know how the OR/M handles translates LINQ to IN SQL clauses and how the OR/M is configured for lazy/eager loading.
To reduce complexity the repository should communicate what kind of queries it support. Using Expression<Func<T, bool>> predicate is like saying throw anything at me and I'll try to handle it. Won't work very well. Again. Take the IN clause as an example. The LINQ statement for it varies between different OR/Ms.
Using expressions also move the responsibility of constructing correct queries to the caller. That means that the unit tests for the caller also have to include tests for validating that the caller makes correct queries. i.e. more complex tests.
I have several product tables in my database:
ProductTypes
ProductCategories
ProductCategoryItems
ProductInventory
The way I see it now, I can make IProduct which would have methods such as:
FindAllTypes()
FindAllCategories(int typeId)
FindAllItems(int categoryId)
Or, I can separate each to mimic the table structure: IProductType, IProductCategory, etc.
Is there a reason to go with one over another?
The idea of repositories is to delegate each one with responsibility for a single entity. In this case making a repository for each entity is recommended. You can go for the big repository one as well, but is not the best solution. In the end you'll get a HUGE class with lots of methods and really tight coupled. Also difficult to give maintenance to.
I don't think having a huge repository is really a good idea, then you'd basically have a data access god class that does everything.
I like to have a base Repository<T> which does common operations such as GetById and GetAll. I normally have all my repositories inherit this base class to get the common methods for free, so I don't have to keep rewriting the same code.
In my opinion it very much depends on the business domain model, it's very important to determine what are your main business entities. Not necessarily every table in the DB is directly mapped to a business entity. Tables are just representations of your one or many entities in a normalized way for relational databases.
Try to picture your domain model beyond the restrictions of normalized relational databases, is there really more than one business concept? Repositories should be constructed around solid, whole, first-class business entities.
My advice would be to have an IProductRepository with the necessary methods to implement CRUD operations and grow it as needed. You don't want to get too ambitious interfaces beacuse you may not need most of it, and it could be a burden. The important thing about interfaces is to decouple your code from the persistence schema, so you can latter offer the flexibility to switch between them.
Maybe in the future the business will need to evolve to a more detailed representation of -for instance- the product's providers, and in that moment you'll use your good judgement to decide wether that represents an important business entity worthy of a dedicated repository or not.
Hope this helps.
I disagree with the others (edit: except with Isaac). The small repositories are a facade (not the pattern).
If the entity types are coupled (have navigation properties to each other) then they are not really separatable.
Modifying one entity type and committing the changes may commit change to others.
Also, you can not create any small repository above the same unit of work,
since the ORM only has a limited amount of entities mapped to the database.
Divide your model into separatable domains and create one specific unit of work for each domain.
On these unit of works create aggregate roots for each entity type that you may require immediate access to.
Each root should have specifically typed add, remove, getbykeys, query and etc methods.
The unit of work should have the commitchanges and alike methods on it.
Each of the roots is similar to the small repositories the others mentioned, however, the unit of work is the real medium sized repository (of which your model may have more than one type of).
Example:
// Create one of these
interface IUnitOfWork
{
void Commit();
}
// Create one of these
interface IEntitySet<TEntity> where TEntity : class
{
void Add(TEntity entity);
void Remove(TEntity entity);
TEntity Create<TSpecificEntity>() where TSpecificEntity : TEntity;
IQueryable<TEntity> Query();
}
// Create one of these per entity type
interace IEntitySetOfTEntity1 : IEntitySet<Entity1>
{
TEntity1 GetByKeys(int key1);
}
interace IEntitySetOfTEntity2 : IEntitySet<Entity2>
{
TEntity1 GetByKeys(short key1, short key2);
}
// Create one of these per separatable domain
interface IDomain1UnitOfWork : IUnitOfWork
{
IEntitySetOfTEntity1 Entity1s
{
get;
}
IEntitySetOfTEntity2 Entity2s
{
get;
}
}
All these interfaces and their implementations can be auto-generated.
These interfaces and their implementations are very light weight and by no means are any of them "a HUGE class with lots of methods". Since they can be auto-generated, maintenance is easy.
Specific functionalities can be added to the interfaces IDomain1UnitOfWork, IEntitySetOfTEntity1 and alike by using:
a. extension methods
b. partial interfaces and classes (less recommended, since this results in a less clean DAL)
The IEntitySetOfTEntity1 like interfaces can be disgarded if you use extension methods to add the GetByKeys() methods to IEntitySet<Entity1>.
What is alternative patterns of using for Entity Framework ?
Some I know are:
"Plain" EntityFramework - aka Unity of Work
using (Data.Model c = new Data.Model())
{
var z = c.Users.Where(x=>x.Name=='John');
}
Repository pattern
//Model implements IRepository
User user = Model.Instance.Get<User>(u => u.Name == "John");
What else ?
?
A good book to look at is Martin Fowler's "Patterns of enterprise application architecture".
There he goes through some patterns for retrieving/mapping data like DTOs, Unit of work, repository pattern etc... Maybe something could be useful together with the Entity Framework. I'd have to take a look at it.
I answer your question based on the assumption that you are using Entity Framework directly in your UI/controller/Services.
It has been proven that using any ORM, inclusing EF, directly in your UI/Controllers/Services will cause a lot of problem in the future. On top of that, it makes it so hard, if not impossible, to unit test your application.
The second approach ie "Model implements repository" is also wrong in my opinion, becuase Model and Respositories have different responsiblities and based on "Single Responsibilty" part of SOLID principles you should not merge the two concepts together. Even if you want to use Active Objects pattern in your model, which I don't recommend, you must decouple your model from the ORM you use.
The best and the most recommended solution is to have an interface like IRepository or IRepository with the very basic members as the pattern suggests. something like:
Interface IRepository<T> where T:class
{
void Insert(T entity);
void Update(T entity);
void Delete(T entity);
// if you don't want to return IQueryable
T FindById(object id);
IEnumerable FindXXXXX(params)
// if you prefer to return an IQueryable
IQueryable<T> Find(Expression<Func<T, bool>> predeicate);
}
Note that some poeple beleive Repositories should not return IQueryable. Additionally, You can consider using ISpecification instead of expressions and lambda.
you would need to implement IRepositoy interface for most of your entities. Using this approach you can also mock your repositories when writing unit tests. In production, you would need to use an Ioc provider such as Unity, Ninject, Linfu, Catsle and etc. you can also benefit from microsoft's common service locator implementation to avoid coupling to a specifi IoC framework.
In the old days, I used to have a data access interface which was impleneted for a specific business domain or a service. One of the issues with this approach is that you would end up with duplicate code in different data access services if you keep track of your source code and you will eventually.
We use code similar to what you have in your unit of work example.
What we do in addition is to map objects to Data Transfer Objects.
There are many articles on the subject, but the list will be reduced substantially if you'd like a good one. This article from MSDN Magazine is pretty good, although it deals specifically with n-tier applications. But since you don't say what you're building, maybe it will help.
LINQ 2 SQL can be an alternative. Here is an article Dependency Injection with Unity and Linq to SQL DataContexts
UNITY - http://unity.codeplex.com/