For some reason, you always get people in life who know something but don't like to explain them - so I have come here in hope to gain some light into what the IRepository Pattern is.
I have about 1 years programming experience and would like for someone to clearly explain to newbies like me how the above pattern works.
I have had mixed messages from several sources and I am now starting to get *%&^$ confused. However, what I have noticed is that often when mentioning the IRepository pattern, other familiar terms are also mentioned such as Domain, Domain Objects, Domain Model, Application Services, Domain Services, Web Services..
Could anybody give an explanation (not massivley in depth but enough to get a good enough picture of what each component means)...please share your experience!
The repository pattern is normally discussed as part of domain driven design (DDD).
The following is over-simplified to get to the point.
DDD is an architecture for constructing applications. In it the developer will define models that mimic the business requirements. For instance, if you're building an e-commerce application you'd have a product model and a cart model (among other things).
In this architecture the repositories are responsible for persisting and retrieving models. After a visitor to our site adds a product to his/her cart we'd construct the cart object var cart = new Cart(sessionId, productId, yada...) then call repository.Save(cart).
To answer your question:
The IRepository and more likely IRepository<T> interfaces are used to simplify your repositories. They typically contain methods like Get(int id) and Save(object o) that aren't going to change whether you're saving a product or a cart (remember, all the information is in the model). In this type of application you'd use one repository to handle all your persistance and only create specialized repositories (e.g. CartRepository) for very specific uses.
Another part of DDD is that the application doesn't care where the models are persisted, just that they are persisted. By creating an interface the application can be configured to persist objects to whatever/wherever without having to change code. In our example application we could have SQLServerRepository, OracleRepository, XmlRepository, and MongoRepository. As long as they implement the IRepository interface our shopping cart will be able to persist (save) objects to a variety of databases or to an XML file.
Take a look here, for the best explanations about Repositories, Domain, etc...
http://en.wikipedia.org/wiki/Domain-driven_design
http://domaindrivendesign.org
http://www.infoq.com/minibooks/domain-driven-design-quickly
Key to understanding mentioned terms is Domain Driven Design. There is a good book Domain Driven Design by Eric Evans. Domain Driven Design is not a standard, not a technology or methodology. It's set of practices in software development. If you will keep these practices you will have some benefits. Benefits will be not in decreasing time for development, not in using some tools, but in maintainability of your code, in testability and so on.
Model is representation of some things from real world. Your goal is to keep the model clean, to do not allow to influence of programming technologies, of data storage restrictions. In this context is important to use Repository pattern.
Let me give a short example of how I use the IReporisotry pattern. Don't take this explanation as "the way of using it", this is just an example.
I have a Silverlight app wich uses EntityFramework on the server side to access the database. I don't know if you are familiar with EntityFramework but among other features it gives you a context where your entities are so you have ask the context for entitites or tell the context to save entities to the database.
That context has many Repositories to handle those entitites. So my app has a SQLReporsitory (implementing my IRepository) that 'knows' how to save entities to the database. So why the heck I implemented the IRepository? Because I also need to test the saving and retrieving of my entities and I can't afford to depend of the data in the database. So I created a "Memory Database" wich holds simple List<T> of entities and knows how to add, retrieve and remove entities from those lists.
So, when I'm running the app, the SqlRepository gets created, and when I'm running the tests the Fake Repository gets created. And the core of my business is not changed at all. I just 'ask' for an entity or whatever and depending on the context where I'm running I get the data from the database or from my in memory database.
Hope it helps
Edit: here's a good example, with code! http://azurecoding.net/blogs/brownie/archive/2010/09/22/irepository-lt-t-gt-and-iunitofwork.aspx
In short, IRepository is an anti-pattern -> http://codebetter.com/gregyoung/2009/01/16/ddd-the-generic-repository/
In C#/.net land there is a great drive to overcomplicate / overdesign programs, even the simplest of CRUD-application has to be DDD and have a domain model and offcourse (wrongly) have a generic repository. Cargo Cult Programming at its finest
You can find a good resource for reviews of overdesigned architectures # http://ayende.com/blog/tags/reviews
Related
I am trying to learn some concepts about DDD and the part of persisting Aggregates is confusing me a bit. I have read various answers on the topic on SO but none of them seem to answer my question.
Let's say I have an Aggregate root of Product. Now I do not want to inject the ProductRepository that will persist this aggregate root in the constructor of the Product class itself. Imagine me writting code like
var prod = new Product(Factory.CreateProductRepository(), name, costprice);
in the UI layer. If I do not want to inject my repository via dependency injection in the Aggregate Root, then the question is where should this code go? Should I create a class only for persisting this AR? Can anyone suggest what is the correct & recommended approach to solve this issue?
My concern is not which ORM to use or how to make this AR ORM friendly or easy to persist, my question is around the right use of repositories or any persistence class.
Application Services
You are right, the domain layer should know nothing about persistence. So injecting the repository into Product is indeed a bad idea.
The DDD concept you are looking for is called Application Service. An application service is not part of the domain layer, but lives in the service layer (sometimes called application layer). Application services represent a use case (as opposed to a domain concept) and have the following responsibilities:
Perform input validation
Enforce access control
Perform transaction control
The last point means that an application service will query a repository for an aggregate of a specific type (e.g. by ID), modify it by using one of its methods, and then pass it back to the repository for updating the DB.
Repository Ganularity
Concerning your second question
Should I create a class only for persisting this AR?
Yes, creating one repository per aggregate is a common approach. Often, standard repository operations like getById(), update(), delete(), etc. are extracted into a reusable class (either a base class or by aggregation).
You can also create additional repositories for non-domain information, e.g. statistical data. In these cases, make sure that you don't accidentally miss a domain concept, however.
I have a project with the following structure:
Project.Domain
Contains all the domain objects
Project.EntityFramework, ref Project.Domain
Contains Entity Framework UnitOfWork
Project.Services, ref Project.Domain and Project.EntityFramework
Contains a list of Service classes that perform some operations on the Domain objects
Project.Web.Mvc, ref to all the projects above
I am trying to enforce some Business rules on top of the Domain objects:
For example, you cannot edit a domain object if it's parent is disabled, or, changing the name of an object, Category for example, needs to update recursively all it's children properties (avoiding / ignoring these rules will result in creating invalid objects)
In order to enforce these rules, i need hide all the public properties setters, making them as internal or private.
In order to do this, i need to move the Project.Services and Project.EntityFramework inside the Project.Domain project.
Is this wrong?
PS: i don't want to over complicate the project by adding IRepositories interfaces which would probably allow me to keep EntityFramework and Domain separate.
PS: i don't want to over complicate the project by adding IRepositories interfaces which would probably allow me to keep EntityFramework and Domain separate.
its really a bad idea, once i had this opinion but honestly if you dont program to abstraction it will become a pain when the project becomes larger. (a real pain)
IRepositories help you spread the job between different team members also. in addition to that you can write many helper extensions for Irepository to encapsulate Different Jobs for example
IReopisotry<File>.Upload()
you must be able to test each layer independently and tying them together will let you only do an integration tests with alot of bugs in lower layers :))
First, I think this question is really opinion based.
According to the Big Book the domain models must be separated from the data access. Your domain has nothing to with the manner of how storing the data. It can be a simple text file or a clustered mssql servers.
This choice must be decided based on the actual project. What is the size of the application?
The other huge question is: how many concurrent user use the db and how complex your business logic will be.
So if it's a complex project or presumably frequently modified or it has educational purposes then you should keep the domain and data access separated. And should define the repository interfaces in the domain model. Use some DI component (personally I like Ninject) and you should not reference the data access component in the services.
And of course you should create the test projects also using some moq tools to test the layers separately.
Yes this is wrong, if you are following Domain Driven Design, you should not compromise your architecture for the sake of doing less work. Your data-access and domain should be kept apart. I would strongly suggest that you implement the Repository pattern as it would allow you more flexibility in the long run.
There are of course to right answer to whats the right design...I would however argue that EF is you data layer abstraction, there is no way youre going to make anything thats more powerful and flexible with repositories.To avoid code repetition you can easily write extension methods (for IQueryable<>) for common tasks.Unit testing of the domain layer is easily handled by substituting you big DB with some in-proc DB (SqlLite / Sql Server Compact).IMHO with the maturity of current ORMs like nHibernate and EF is a huge waste of money and time to implement repositories for something as simple as DB access.
Blog post with a more detailed reply; http://ayende.com/blog/4784/architecting-in-the-pit-of-doom-the-evils-of-the-repository-abstraction-layer
Every example of the Repository Pattern I have seen deals with a very simple use case - one object type and the most basic CRUD operations. The Repository is then very often plugged straight into an MVC controller.
Real-world data access just isn't like this. Real-world data access scenarios can involve complex graphs of objects and some form of transactional wrapper. For example, suppose I want to save a new Order. This involves writing to the Order, OrderDetails, Invoice, User, History and ItemStock tables. All of this must be transacted, committed or rolled back. Normally I'd pass around something like an IDbTransaction and an IDbConnection and bundles the whole operation in a service layer.
Where does the Repository Pattern fit with this? Am I missing something (Unit Of Work perhaps)? Are there any more realistic examples of Repositories in use than the usual canned blog snippets?
Appreciate any light.
This is a very controversial subject but here is my catch from my own experience.
Repository works at the aggregate root. For example if an OrderItem is always retrieved as part of Order and does not have a life of its own outside order, then it will be loaded by the OrderRepository, otherwise it will have its own repository.
UnitOfWork is an important concept. Let's say OrderItem is an aggregate root and has its own repository. So at the time of creating an order, OrderManager will create a UnitOfWork of work in a using block, initialise OrderItemRepository and OrderRepository and then commit.
UPDATE
Yes, exactly. Imagine - in our case order - an order is being inserted. This needs to be in control of the transaction and enter order and order items separately inside the same transaction. This cannot be managed at the repository level. This is the sole reason for existence of UnitOfWork concept which is passed to the repository so that it does not own or initialise it. UnitOfWork usually is created at the business layer.
O/R-Mappers like Hibernate basically implement the Repository pattern for object graphs while fully supporting transactions. It's often a leaky abstraction, but it certainly can be made to work in complex real-world scenarios.
If you need a good full blown, widely used expample of the repository pattern look at Cocoa's Core Data I realize it is not in the realm of programming languages that you note. But note that it is NOT an O/R mapper. It is a complete abstraction of an object store. No Sql statements to execute, and while you may pick the format of the external storage that is used, you never interact with it directly.
I like to think of a repository as another layer of abstraction. You should only add layers of abstraction when the cost of their implementation is less than the cost of NOT doing the implementation (code maintenance, support, enhancements, etc).
Remember that the purpose of the repository pattern is to separate the logic that retrieves the data (CRUD) and maps it to the entity model from the business logic that acts on the model. What this often ends up doing/looking like in the real world is some form of business entities, that abstract the underlying physical data model.
As far as your transaction question, yes, this relates more to the Unit of Work pattern. Since you mentioned services, I would encourage you to NOT pass around your connection to your various data access classes/methods, but to instead allow WCF to manage the transaction for you using auto enlistment. Here is an extract of Juval Lowy's WCF book (highly recommended) that explains the how and why of this method of transaction management.
So to answer your question, the repository pattern fits in as a way to abstract the physical data model and to separate the CRUD/mapping from the business logic.
I'm implementing a DAL using entity framework. On our application, we have three layers (DAL, business layer and presentation). This is a web app. When we began implementing the DAL, our team thought that DAL should have classes whose methods receive a ObjectContext given by services on the business layer and operate over it. The rationale behind this decision is that different ObjectContexts see diferent DB states, so some operations can be rejected due to problems with foreign keys match and other inconsistencies.
We noticed that generating and propagating an object context from the services layer generates high coupling between layers. Therefore we decided to use DTOs mapped by Automapper (not unmanaged entities or self-tracking entities arguing high coupling, exposing entities to upper layers and low efficiency) and UnitOfWork. So, here are my questions:
Is this the correct approach to design a web application's DAL? Why?
If you answered "yes" to 1., how is this to be reconciled the concept of DTO with the UnitOfWork patterns?
If you answered "no" to 1., which could be a correct approach to design a DAL for a Web application?
Please, if possible give bibliography supporting your answer.
About the current design:
The application has been planned to be developed on three layers: Presentation, business and DAL. Business layer has both facades and services
There is an interface called ITransaction (with only two methods to dispose and save changes) only visible at services. To manage a transaction, there is a class Transaction extending a ObjectContext and ITransaction. We've designed this having in mind that at business layer we do not want other ObjectContext methods to be accessible.
On the DAL, we created an abstract repository using two generic types (one for the entity and the other for its associated DTO). This repository has CRUD methods implemented in a generic way and two generic methods to map the DTOs and entities of the generic repository with AutoMapper. The abstract repository constructor takes an ITransaction as argument and it expects the ITransaction to be an ObjectContext in order to assign it to its proctected ObjectContext property.
The concrete repositories should only receive and return .net types and DTOs.
We now are facing this problem: the generic method to create does not generate a temporal or a persistent id for the attached entities (until we use SaveChanges(), therefore breaking the transactionality we want); this implies that service methods cannot use it to associate DTOs in the BL)
There are a number of things going on here...The assumption I'll make is that you're using a 3-Tier architecture. That said, I'm unclear on a few design decisions you've made and what the motivations were behind making them. In general, I would say that your ObjectContext should not be passed around in your classes. There should be some sort of manager or repository class which handles the connection management. This solves your DB state management issue. I find that a Repository pattern works really well here. From there, you should be able to implement the unit of work pattern fairly easily since your connection management will be handled in one place. Given what I know about your architecture, I would say that you should be using a POCO strategy. Using POCOs does not tightly couple you to any ORM provider. The advantage is that your POCOs will be able to interact with your ObjectContext (probably via Repository of some sort) and this will give you visibility into change tracking. Again, from there you will be able to implement the Unit of Work (transaction) pattern to give you full control over how your business transaction should behave. I find this is an incredibly useful article for explaining how all this fits together. The code is buggy but accurately illustrates best practices for the type of architecture you're describing: Repository, Specification and Unit of Work Implementation
The short version of my answer to question number 1 is "no". The above link provides what I believe to be a better approach for you.
I always believed that code can explain things better than worlds for programmers. And this is especially true for this topic. Thats why I suggest you to look at the great sample application in witch all consepts you expecting are implemented.
Project is called Sharp Architecture, it is centered around MVC and NHibernate, but you can use the same approaches just replacing NHibernate parts with EF ones when you need them. The purpose of this project is to provide an application template with all community best practices for building web applications.
It covers all common and most of the uncommon topics when using ORM's, managing transactions, managing dependencies with IoC containers, use of DTOs, etc.
And here is a sample application.
I insist on reading and trying this, it will be a real trasure for you like it was for me.
You should take a look what dependency injection and inversion of control in general means. That would provide ability to control life cycle of ObjectContext "from outside". You could ensure that only 1 instance of object context is used for every http request. To avoid managing dependencies manually, I would recommend using StructureMap as a container.
Another useful (but quite tricky and hard to do it right) technique is abstraction of persistence. Instead of using ObjectContext directly, You would use so called Repository which is responsible to provide collection like API for Your data store. This provides useful seam which You can use to switch underlying data storing mechanism or to mock out persistence completely for tests.
As Jason suggested already - You should also use POCO`s (plain old clr objects). Despite that there would still be implicit coupling with entity framework You should be aware of, it's much better than using generated classes.
Things You might not find elsewhere fast enough:
Try to avoid usage of unit of work. Your model should define transactional boundaries.
Try to avoid usage of generic repositories (do note point about IQueryable too).
It's not mandatory to spam Your code with repository pattern name.
Also, You might enjoy reading about domain driven design. It helps to deal with complex business logic and gives great guidelines to makes code less procedural, more object oriented.
I'll focus on your current issues: To be honest, I don't think you should be passing around your ObjectContext. I think that is going to lead to problems. I'm assuming that a controller or a business service will be passing the ObjectContext/ITransaction to the Repository. How will you ensure that your ObjectContext is disposed of properly down stream? What happens when you use nested transactions? What manages the rollbacks, for transactions down stream?
I think your best bet lies in putting some more definition around how you expect to manage transactions in your architecture. Using TransactionScope in your controller/service is a good start since the ObjectContext respects it. Of course you may need to take into account that controllers/services may make calls to other controllers/services which have transactions in them. In order to allow for scenarios where you want full control over your business transactions and the subsequent database calls, you'll need to create some sort of TransactionManager class which enlists, and generally manages transactions up and down your stack. I've found that NCommon does an extraordinary job at both abstracting and managing transactions. Take a look at UnitOfWorkScope and TransactionManager classes in there. Although I disagree with NCommon's approach of forcing the Repository to rely on the UnitOfWork, that could easily be refactored out if you wanted.
As far as your persistantID issue goes, check this out
I have been trying to learn and apply domain driven concept into my software development. The first thing that I try to do is creating my domain model based on business logic needs. I often also use OR Mapping tool, such as LLBLGen, NHibernate, or Linq to SQL, to create data model and data access layer. The domain model and data model, however, are often very similar which make me wonder what benefit I really get by maintaining two models.
Can someone share their practical thoughts about domain driven design? Furthermore, how would you deal with data model or data access layer when applying DDD in your application?
Thanks in advance.
EDIT
Found a good article, with sample code, about Repository Pattern.
I abstract my data access via the Repository pattern, so keep my domain objects completely POCO and data provider agnostic.
This allows me to sculpt my application from a domain perspective, concentrating on the logic, primarily via Unit Tests.
Once this has settled I put in the Presentation layer (usually web pages) and then commit to the concrete database schema. I then implement my concrete Repository classes, which can be L2S.
I've drafted a couple of articles here - http://www.duncangunn.me.uk/dasblog/2009/04/11/TheRepositoryPattern.aspx
http://www.duncangunn.me.uk/dasblog/2009/06/27/MockingLinqToSQLRepositories.aspx
Keep an eye out over the next couple of weeks as I will be documenting and providing sample code of my implementation which uses Unit of Work pattern also.
We map domain objects directly to the database, means that we do not have separate layer for data access, and rather we treat this as infrastructure code.
We use Fluent NHibernate for most of the configuration.
Splitting bounded contexts is also a big DDD benefit, you resolve each problem in its context, even if you must duplicate data between contexts.
Good aggregate roots definition gives a simpler design and leads to potential performance improvement (scalability through grid computing, see Gojko Adzic post).
When your design becomes really Domain Driven, your applications is more supple to new business needs, because implementation becomes really an implementation detail.