HTML5技术

EntityFramework系列:Repository模式与单元测试 - #王刚

字号+ 作者:H5之家 来源:博客园 2016-01-22 12:00 我要评论( )

1.依赖IRepository接口而不是直接使用EntityFramework 使用IRepository不只是架构上解耦的需要,更重要的意义在于Service的 单元测试 ,Repository模式本身就是采用集合操作的方式简化数据访问,IRepository更容易Mock。先上图: 鉴于目前接触到的项目中,即

1.依赖IRepository接口而不是直接使用EntityFramework

使用IRepository不只是架构上解耦的需要,更重要的意义在于Service的单元测试,Repository模式本身就是采用集合操作的方式简化数据访问,IRepository更容易Mock。先上图:

鉴于目前接触到的项目中,即使业务逻辑相对复杂的项目也只是应用逻辑复杂而非领域逻辑复杂,在实际使用中聚合根和单独Repository接口只是引入了更多的代码和类型定义,因此一般情况下使用泛型版本的Repository<T>接口即可。nopcommerce等开源项目中也是如此。Java中的伪泛型无法实现泛型版本的Repository<T>,简单的说你无法在Repository<T>的方法中获取T的类型。

1 namespace Example.Application 2 { IRepository<T> where T : class 4 { 5 T FindBy(object id); 6 7 IQueryable<T> Query { get; } Add(T entity); Remove(T entity); Update(T entity); Commit(); 16 } 17 }

2.封装DbContext的依赖项

(1)定义一个通用的EfDbContext,将DbContext对IDbConnectionFactory、ConnectionString、实体类配置等的依赖封装到DbSettings中,既可以在使用使方便依赖注入也方便进行单元测试。

1 namespace Example.Infrastructure.Repository 2 { EfDbContext : DbContext, IDbContext 4 { 5 private DbSettings _dbSettings; EfDbContext(IConfiguration configuration, ILogger logger, DbSettings dbSettings) : base(dbSettings.NameOrConnectionString) 8 { 9 this._dbSettings = dbSettings; 10 if (this._dbSettings.DbConnectionFactory != null) 11 { 12 #pragma warning disable 13 Database.DefaultConnectionFactory = this._dbSettings.DbConnectionFactory; 14 } , false)) 16 { 17 this.Database.Log = sql => logger.Information(sql); 18 } 19 this.Database.Log = l => System.Diagnostics.Debug.WriteLine(l); 20 } OnModelCreating(DbModelBuilder modelBuilder) 23 { 24 base.OnModelCreating(modelBuilder); 25 26 modelBuilder.Conventions.Remove<PluralizingTableNameConvention>(); 27 if (_dbSettings.EntityMaps != null) 28 { 29 foreach (var item in _dbSettings.EntityMaps) 30 { 31 modelBuilder.Configurations.Add((dynamic)item); 32 } 33 } 34 if (_dbSettings.ComplexMaps != null) 35 { 36 foreach (var item in _dbSettings.ComplexMaps) 37 { 38 modelBuilder.Configurations.Add((dynamic)item); 39 } 40 } 41 } SetInitializer<T>() where T : DbContext 44 { 45 if (this._dbSettings.Debug) 46 { 47 if (this._dbSettings.UnitTest) 48 { 49 Database.SetInitializer(new DropCreateDatabaseAlways<T>()); 50 } 51 { 52 Database.SetInitializer(new DropCreateDatabaseIfModelChanges<T>()); 53 } 54 } { 57 Database.SetInitializer<T>(null); 58 } 59 } IDbSet<T> Set<T>() where T : class 62 { .Set<T>(); 64 } Commit() 67 { .SaveChanges(); 69 } 70 } 71 }

(2)在DbSettings中按需定义依赖,这里将实体类的配置也通过DbSettings注入。

 

1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

相关文章
  • HTML5 进阶系列:拖放 API 实现拖放排序 - _林鑫

    HTML5 进阶系列:拖放 API 实现拖放排序 - _林鑫

    2017-05-02 11:02

  • JS组件系列——自己动手封装bootstrap-treegrid组件 - 懒得安分

    JS组件系列——自己动手封装bootstrap-treegrid组件 - 懒得安分

    2017-04-28 14:02

  • HTML5 进阶系列:indexedDB 数据库 - _林鑫

    HTML5 进阶系列:indexedDB 数据库 - _林鑫

    2017-04-27 14:02

  • HTML5 高级系列:web Storage - _林鑫

    HTML5 高级系列:web Storage - _林鑫

    2017-04-27 14:01

网友点评