Repository commonly refers to a storage location, often for safety or preservation.
Objectives of using repository
Use the Repository
pattern to achieve one or more of the following objectives:
- You want to maximize the amount of code that can be
tested with automation and to isolate the data layer to support unit
testing.
- You access the data source from many locations and want
to apply centrally managed, consistent access rules and logic.
- You want to implement and centralize a caching strategy
for the data source.
- You want to improve the code's maintainability and
readability by separating business logic from data or service access
logic.
- You want to use business entities that are strongly
typed so that you can identify problems at compile time instead of at run
time.
- You want to associate a behavior with the related data.
For example, you want to calculate fields or enforce complex relationships
or business rules between the data elements within an entity.
- You want to apply a domain model to simplify complex
business logic.
Solution
Use a repository to
separate the logic that retrieves the data and maps it to the entity model from
the business logic that acts on the model. The business logic should be
agnostic to the type of data that comprises the data source layer. For example,
the data source layer can be a database, a SharePoint list, or a Web service.
The repository
mediates between the data source layer and the business layers of the
application. It queries the data source for the data, maps the data from the
data source to a business entity, and persists changes in the business entity
to the data source. A repository separates the business logic from the interactions
with the underlying data source or Web service. The separation between the data
and business tiers has three benefits:
- It centralizes the data logic or Web service access
logic.
- It provides a substitution point for the unit tests.
- It provides a flexible architecture that can be adapted
as the overall design of the application evolves.
The repository pattern
is an abstraction. Its purpose is to reduce complexity and make the rest of the
code persistent ignorant. As a bonus it allows you to write unit tests instead
of integration tests. The problem is that many developers fail to understand
the patterns purpose and create repositories which leak persistence specific
information up to the caller (typically by exposing IQueryable<T>, read through Mark Seemann’s blog IQueryable is Tight Coupling ).
The Repository Pattern is a common construct to avoid duplication of data
access logic throughout our application. This includes direct access to a
database, ORM, WCF dataservices, xml files and so on. We can
easily query the repository for data objects, without having to know how to
provide things like a connection string. The repository behaves like a
freely available in-memory data collection to which we can add, delete and
update objects.
The Repository pattern
adds a separation layer between the data and domain layers of an application.
It also makes the data access parts of an application better testable. Using
repositories is not about being able to switch persistence technology (i.e. changing
database or using a web service etc instead).
Creating Repository is
not as tough as it sounds to be, once you implement this by your own, you’ll
love it for sure.
Create Repository pattern
Step1 Very first thing to
create a repository is to define an interface inside which we declare CRUD
operations on entity.
using System;
using System.Linq;
using System.Linq.Expressions;
namespace Demo.Repositories
{
public interface IRepository
{
void Insert(T entity);
void Delete(T entity);
List<T> SearchFor(Expression<Func<T, bool>> predicate);
List<T> GetAll();
T GetById(int id);
}
}
Step2 Create a
class inheriting the interface, pretty straight forward approach.
using
System;
using System.Data.Linq;
using System.Linq;
using System.Linq.Expressions;
namespace Demo.Repositories
{
public class
Repository<T> : IRepository<T>
where T : class,
IEntity
{
protected Table<T>
DataTable;
public Repository(DataContext
dataContext)
{
DataTable = dataContext.GetTable<T>();
}
#region IRepository<T> Members
public void
Insert(T entity)
{
DataTable.InsertOnSubmit(entity);
}
public void
Delete(T entity)
{
DataTable.DeleteOnSubmit(entity);
}
public IQueryable<T>
SearchFor(Expression<Func<T, bool>>
predicate)
{
return
DataTable.Where(predicate);
}
public IQueryable<T>
GetAll()
{
return
DataTable;
}
#endregion
}
}
Now the major part of
our job is done.
Step 3 Use the repository in the application
using System;
using System.Collections.Generic;
using System.Linq;
using
Demo.Repositories;
namespace
LinqToSqlRepositoryConsole
{
internal class
Program
{
private static
void Main()
{
using
(var dataContext = new HotelsDataContext())
{
var hotelRepository = new Repository<Hotel>(dataContext);
var cityRepository = new Repository<City>(dataContext);
City
city = cityRepository
.SearchFor(c => c.Name.StartsWith("Mum"))
.Single();
IEnumerable<Hotel> orderedHotels = hotelRepository
.GetAll()
.Where(c =>
c.City.Equals(city))
.OrderBy(h => h.Name);
Console.WriteLine("* Hotels in {0} *", city.Name);
foreach
(Hotel orderedHotel in
orderedHotels)
{
Console.WriteLine(orderedHotel.Name);
}
Console.ReadKey();
}
}
}
}
Now that we have most of the things ready we can refine our functionality
as per our choice, add more
entity specific operations.
No comments:
Post a Comment