I have implemented a repository pattern, with EF and a seperate mapping class where I set table key ID and relations. In the data context implementation, I reference this mappers to the DbSets.
Mapper:
internal static class ProductMapper
{
internal static void BuildMapping(DbModelBuilder modelBuilder)
{
var tbl = modelBuilder.Entity<Product>();
//Primary key
tbl.HasKey(t => t.ID);
//Table and column mappings
tbl.ToTable("Product");
//Relationships
tbl.HasRequired(t => t.ProductCategory).WithMany(t => t.Products).HasForeignKey(d => d.ProductCategoryID);
}
}
DBContext
public class ProductContext : DbContext
{
public ProductContext() : base("ProductDatabase")
{
Database.SetInitializer<ProductContext>(null);
base.Configuration.LazyLoadingEnabled = false;
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
var typesToRegister = Assembly.GetAssembly(typeof(Kyocera.ProductServices.DataAccess.EF.Mappers.ComposedPropertyMapper)).GetTypes()
.Where(type => type.Namespace != null && type.Namespace.Equals(typeof(Kyocera.ProductServices.DataAccess.EF.Mappers.ComposedPropertyMapper).Namespace))
.Where(type => type.BaseType.IsGenericType && type.BaseType.GetGenericTypeDefinition() == typeof(EntityTypeConfiguration<>));
foreach (var type in typesToRegister)
{
dynamic configurationInstance = Activator.CreateInstance(type);
modelBuilder.Configurations.Add(configurationInstance);
}
}
public virtual DbSet<Product> Products { get; set; }
public virtual DbSet<ProductCategory> ProductCategories { get; set; }
}
For the unit testing, I have a seperate implementation for the DBContext and DBSets:
FakeDbContext
public abstract class FakeDbContext : IFakeDBContext
{
#region Private Fields
private readonly Dictionary<Type, object> _fakeDbSets;
#endregion Private Fields
protected FakeDbContext()
{
_fakeDbSets = new Dictionary<Type, object>();
}
public int SaveChanges() { return default(int); }
public void SyncObjectState<TEntity>(TEntity entity) where TEntity : class, IObjectState
{
// no implentation needed, unit tests which uses FakeDbContext since there is no actual database for unit tests,
// there is no actual DbContext to sync with, please look at the Integration Tests for test that will run against an actual database.
}
public Task<int> SaveChangesAsync(CancellationToken cancellationToken) { return new Task<int>(() => default(int)); }
public Task<int> SaveChangesAsync() { return new Task<int>(() => default(int)); }
public void Dispose() { }
public DbSet<T> Set<T>() where T : class { return (DbSet<T>)_fakeDbSets[typeof(T)]; }
public void AddFakeDbSet<TEntity, TFakeDbSet>()
where TEntity : Entity, new()
where TFakeDbSet : FakeDbSet<TEntity>, IDbSet<TEntity>, new()
{
var fakeDbSet = Activator.CreateInstance<TFakeDbSet>();
_fakeDbSets.Add(typeof(TEntity), fakeDbSet);
}
public void SyncObjectsStatePostCommit() { }
}
ProductDbContext for unit testing
public class ProductDbContext : FakeDbContext
{
public ProductDbContext()
{
AddFakeDbSet <Product, ProductDbSet>();
AddFakeDbSet <ProductGroup, ProductGroupDbSet>();
}
}
public class ProductDbSet : FakeDbSet<Product> { }
public class ProductGroupDbSet : FakeDbSet<ProductGroup> { }
}
Can I use the mapper also in this fake db context? And if yes, where?
Aucun commentaire:
Enregistrer un commentaire