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.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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(); | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public abstract class DataRepositoryBase<T> : DataRepositoryBase<T, CarRentalContext> | |
where T : class, IIdentifiableEntity, new() | |
{ | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public interface IIdentifiableEntity | |
{ | |
int EntityId { get; set; } | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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