共用方式為


Repository Pattern – The purpose

We decided to implement the repository pattern for the Entity Framework Implementation in our project. So last couple of weeks people have been asking me why the repository pattern is required. I mean what is it that this pattern does besides giving a layer of abstraction, and providing the CRUD methods, which are also available in C# as a language feature (LINQ).

The answer is given aptly by Martin Fowler as, “A system with a complex domain model often benefits from a layer, such as the one provided by Data Mapper (165), that isolates domain objects from details of the database access code. In such systems it can be worthwhile to build another layer of abstraction over the mapping layer where query construction code is concentrated. This becomes more important when there are a large number of domain classes or heavy querying. In these cases particularly, adding this layer helps minimize duplicate query logic.

A Repository mediates between the domain and data mapping layers, acting like an in-memory domain object collection. Client objects construct query specifications declaratively and submit them to Repository for satisfaction. Objects can be added to and removed from the Repository, as they can from a simple collection of objects, and the mapping code encapsulated by the Repository will carry out the appropriate operations behind the scenes. Conceptually, a Repository encapsulates the set of objects persisted in a data store and the operations performed over them, providing a more object-oriented view of the persistence layer. Repository also supports the objective of achieving a clean separation and one-way dependency between the domain and data mapping layers.”

This has a no. of benefits. Simplifying complexity, removing redundant querying, making code more testable, etc. Let’s say you want to test your code without going into the database and destroying it completely. unless you use DBUnit, This pattern helps you a lot. All you need to do is change your SaveChanges() function from

---

        /// <summary>
        /// Saves all changes in the current context.
        /// </summary>
        public virtual int SaveAllChanges()
        {
            try
            {
                ((ObjectContext)this.Context).SaveChanges();
                return 0;
            }
            catch
            {
                return -1;
            }
        }

---

to

---

        /// <summary>
        /// Saves all changes in the current context.
        /// </summary>
        public virtual int SaveAllChanges()
        {
                return 0;
        }

---

On doing this, your changes are not populated to the database and you can do all your testing in-memory. Now is it a good idea to change your code to just make it testable? Well that’s a good question that needs discussing at length. Maybe in another post…