Monday, 13 October 2014

Example of DataRepository pattern

Here is a quick example of a data repository pattern used with EF. Note the UpdateEntity method in AccountRepository purely returns the entity to be updated, this perhaps should be named more clearly.

public class AccountRepository : DataRepositoryBase<Account>, IAccountRepository
{
protected override Account AddEntity(CarRentalContext entityContext, Account entity)
{
return entityContext.AccountSet.Add(entity);
}
protected override Account UpdateEntity(CarRentalContext entityContext, Account entity)
{
return (from e in entityContext.AccountSet
where e.AccountId == entity.AccountId
select e).FirstOrDefault();
}
protected override IEnumerable<Account> GetEntities(CarRentalContext entityContext)
{
return from e in entityContext.AccountSet
select e;
}
protected override Account GetEntity(CarRentalContext entityContext, int id)
{
var query = (from e in entityContext.AccountSet
where e.AccountId == id
select e);
var results = query.FirstOrDefault();
return results;
}
public Account GetByLogin(string login)
{
using (CarRentalContext entityContext = new CarRentalContext())
{
return (from a in entityContext.AccountSet
where a.LoginEmail == login
select a).FirstOrDefault();
}
}
}
public abstract class DataRepositoryBase<T> : DataRepositoryBase<T, CarRentalContext>
where T : class, IIdentifiableEntity, new()
{
}
public abstract class DataRepositoryBase<T, U> : IDataRepository<T>
where T : class, IIdentifiableEntity, new()
where U : DbContext, new()
{
protected abstract T AddEntity(U entityContext, T entity);
protected abstract T UpdateEntity(U entityContext, T entity);
protected abstract IEnumerable<T> GetEntities(U entityContext);
protected abstract T GetEntity(U entityContext, int id);
public T Add(T entity)
{
using (U entityContext = new U())
{
T addedEntity = AddEntity(entityContext, entity);
entityContext.SaveChanges();
return addedEntity;
}
}
public void Remove(T entity)
{
using (U entityContext = new U())
{
entityContext.Entry<T>(entity).State = EntityState.Deleted;
entityContext.SaveChanges();
}
}
public void Remove(int id)
{
using (U entityContext = new U())
{
T entity = GetEntity(entityContext, id);
entityContext.Entry<T>(entity).State = EntityState.Deleted;
entityContext.SaveChanges();
}
}
public T Update(T entity)
{
using (U entityContext = new U())
{
T existingEntity = UpdateEntity(entityContext, entity);
SimpleMapper.PropertyMap(entity, existingEntity);
entityContext.SaveChanges();
return existingEntity;
}
}
public IEnumerable<T> Get()
{
using (U entityContext = new U())
return (GetEntities(entityContext)).ToArray().ToList();
}
public T Get(int id)
{
using (U entityContext = new U())
return GetEntity(entityContext, id);
}
}
public interface IDataRepository
{
}
public interface IDataRepository<T> : IDataRepository
where T : class, IIdentifiableEntity, new()
{
T Add(T entity);
void Remove(T entity);
void Remove(int id);
T Update(T entity);
IEnumerable<T> Get();
T Get(int id);
}
public interface IIdentifiableEntity
{
int EntityId { get; set; }
}
using System;
using System.Collections.Generic;
using System.ComponentModel.Composition;
using CarRental.Business.Bootstrapper;
using CarRental.Business.Entities;
using CarRental.Data.Contracts;
using Core.Common.Contracts;
using Core.Common.Core;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Moq;
namespace CarRental.Data.Tests
{
[TestClass]
public class DataLayerTests
{
[TestInitialize]
public void Initialize()
{
ObjectBase.Container = MEFLoader.Init();
}
[TestMethod]
public void test_repository_usage()
{
RepositoryTestClass repositoryTest = new RepositoryTestClass();
IEnumerable<Car> cars = repositoryTest.GetCars();
Assert.IsTrue(cars != null);
}
[TestMethod]
public void test_repository_factory_usage()
{
RepositoryFactoryTestClass factoryTest = new RepositoryFactoryTestClass();
IEnumerable<Car> cars = factoryTest.GetCars();
Assert.IsTrue(cars != null);
}
[TestMethod]
public void test_repository_mocking()
{
List<Car> cars = new List<Car>()
{
new Car() { CarId = 1, Description = "Mustang" },
new Car() { CarId = 2, Description = "Corvette" }
};
Mock<ICarRepository> mockCarRepository = new Mock<ICarRepository>();
mockCarRepository.Setup(obj => obj.Get()).Returns(cars);
RepositoryTestClass repositoryTest = new RepositoryTestClass(mockCarRepository.Object);
IEnumerable<Car> ret = repositoryTest.GetCars();
Assert.IsTrue(ret == cars);
}
[TestMethod]
public void test_factory_mocking1()
{
List<Car> cars = new List<Car>()
{
new Car() { CarId = 1, Description = "Mustang" },
new Car() { CarId = 2, Description = "Corvette" }
};
Mock<IDataRepositoryFactory> mockDataRepository = new Mock<IDataRepositoryFactory>();
mockDataRepository.Setup(obj => obj.GetDataRepository<ICarRepository>().Get()).Returns(cars);
RepositoryFactoryTestClass factoryTest = new RepositoryFactoryTestClass(mockDataRepository.Object);
IEnumerable<Car> ret = factoryTest.GetCars();
Assert.IsTrue(ret == cars);
}
[TestMethod]
public void test_factory_mocking2()
{
List<Car> cars = new List<Car>()
{
new Car() { CarId = 1, Description = "Mustang" },
new Car() { CarId = 2, Description = "Corvette" }
};
Mock<ICarRepository> mockCarRepository = new Mock<ICarRepository>();
mockCarRepository.Setup(obj => obj.Get()).Returns(cars);
Mock<IDataRepositoryFactory> mockDataRepository = new Mock<IDataRepositoryFactory>();
mockDataRepository.Setup(obj => obj.GetDataRepository<ICarRepository>()).Returns(mockCarRepository.Object);
RepositoryFactoryTestClass factoryTest = new RepositoryFactoryTestClass(mockDataRepository.Object);
IEnumerable<Car> ret = factoryTest.GetCars();
Assert.IsTrue(ret == cars);
}
}
public class RepositoryTestClass
{
public RepositoryTestClass()
{
ObjectBase.Container.SatisfyImportsOnce(this);
}
public RepositoryTestClass(ICarRepository carRepository)
{
_CarRepository = carRepository;
}
[Import]
ICarRepository _CarRepository;
public IEnumerable<Car> GetCars()
{
IEnumerable<Car> cars = _CarRepository.Get();
return cars;
}
}
public class RepositoryFactoryTestClass
{
public RepositoryFactoryTestClass()
{
ObjectBase.Container.SatisfyImportsOnce(this);
}
public RepositoryFactoryTestClass(IDataRepositoryFactory dataRepositoryFactory)
{
_DataRepositoryFactory = dataRepositoryFactory;
}
[Import]
IDataRepositoryFactory _DataRepositoryFactory;
public IEnumerable<Car> GetCars()
{
ICarRepository carRepository = _DataRepositoryFactory.GetDataRepository<ICarRepository>();
IEnumerable<Car> cars = carRepository.Get();
return cars;
}
}
}

This example was taken from Miguel Castro and uses MEF as it's DI container.

No comments:

Post a Comment