加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c# – EF6 DbContext IOC依赖关系

发布时间:2020-12-15 08:21:30 所属栏目:百科 来源:网络整理
导读:我在 Windows服务/控制台应用程序中使用EF6.我成功了 为我的业务层接口和实现实现了IOC / DI. 使用构造函数注入.我也在使用对象数据库,任务并行库.为了更好的表现,我很高兴. 还使用System.IO.Abstractions使我的代码更易于测试. EF6使用完全相同的.tt文件为
我在 Windows服务/控制台应用程序中使用EF6.我成功了
为我的业务层接口和实现实现了IOC / DI.
使用构造函数注入.我也在使用对象数据库,任务并行库.为了更好的表现,我很高兴.

还使用System.IO.Abstractions使我的代码更易于测试.

EF6使用完全相同的.tt文件为所有域实体创建POCO clases
便利.为了执行数据库查询,我写的每一个地方

using(var db = new MyContext())
{
// code reading from/writing to database
...
...
}

我知道这不是正确的做法,并在我的代码中的各个地方发出噪音.
我想让它松散耦合.现在我的数据库操作 – 我
困惑如何前进,使其更加可测试和松散耦合.任何人都可以指出一个很好的例子,可以参考的文章.

我想要实现的两件大事就是要有更多的控制权
连接字符串配置(用于各种服务器部署)并使DbContext在我的代码中非常松散地耦合.

解决方法

要解决分离(和测试)问题,您可以为DbContext(IMyDbContext)创建自己的接口,并重新公开所有类型化的实体DbSets,SaveChanges()以及可能的其他一些方法.您还应该使此接口为Disposable.
public interface IMyDbContext : IDisposable
{
    IDbSet<Foo> Foos { get; set; }
    IDbSet<Bar> Bars { get; set; }

    int SaveChanges();
    DbEntityEntry<T> Entry<T>(T entity) where T : class;
}

(您也可以考虑接口的只读和读写版本)

然后更改具体的DbContext以实现此接口.您现在可以合理地与DbContext(用于单元测试等)分离,但仍然可以访问IQueryable的有用性,固有工作单元和DbContext提供的缓存.

然后,这里有两个选项,用于将IMyDbContext注入到您的业务/服务类中

>构造函数注入IDbContext

要么

>创建一个Factory方法和一个Factory接口,用于创建具体的DbContexts,然后对IMyDbContextFactory工厂接口进行构造函数注入(您将需要接口,而不是具体工厂,再次用于模拟测试目的).

这里的选择取决于您需要对DbContext执行的操作.在IoC容器中配置#1可能很棘手,因为您需要将生命周期管理移交给容器.但是,如果可以为每个请求配置新实例,那么这在Web应用程序中可能是有益的,因此如果请求(假设单个线程)可以将其用作缓存.

我个人更喜欢#2,因为这允许直接管理上下文:

using(var db = _myContextFactory.CreateDB())
{
    db.SaveChanges();
}

但显然,我们失去了长期环境(如缓存)的任何潜在好处.但是,如果需要,还有许多其他替代技术可用于缓存.

需要注意的是:DbContext根本不是线程安全的 – 如果您使用的是TPL,请确保每个任务都获得自己的DbContext实例 – 例如使用Parallel.For / ForEach的localinit重载在使用它时实例化它.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读