gpt4 book ai didi

c# - EF6 DbContext IOC 依赖

转载 作者:太空狗 更新时间:2023-10-29 20:09:53 26 4
gpt4 key购买 nike

我在 Windows 服务/控制台应用程序中使用 EF6。我已经成功为我的业务层接口(interface)和实现实现了 IOC/DI。使用构造函数注入(inject)。我也在使用对象数据库、任务并行库。以获得更好的性能,我对此感到满意。

同时使用 System.IO.Abstractions使我的代码更易于测试。

EF6 使用 .tt 文件为所有域实体创建 POCO 类便利。为了执行数据库查询,我在每个地方都写了

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

我知道这不是正确的做法,并且会在我的代码的各个地方发出噪音。我想让它松耦合。现在进行我的数据库操作 - 我是对如何前进以使其更具可测试性和松散耦合感到困惑。任何人都可以给我一个很好的例子,可以引用的文章。

我想要实现的 2 件主要事情是对连接字符串配置(用于各种服务器部署)并使 DbContext 在我的代码中非常松散地耦合。

最佳答案

为了解决耦合(和测试)问题,您可以为您的 DbContext (IMyDbContext) 创建自己的接口(interface),并重新公开所有类型化实体 DbSets SaveChanges(),可能还有一些其他方法。您还应该将此接口(interface)设置为 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;
}

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

然后更改您的具体 DbContext 以实现此接口(interface)。您现在与 DbContext 合理分离(用于单元测试等),但仍然可以访问 IQueryable 的有用性、工作的固有单元以及由DbContext

然后,这里有两个选项可以将 IMyDbContext 注入(inject)到您的业务/服务类中

  1. IDbContext 的构造函数注入(inject)

  1. 为创建具体的 DbContext 创建一个 Factory 方法和一个 Factory 接口(interface),然后对 IMyDbContextFactory 工厂接口(interface)进行构造函数注入(inject)(您需要接口(interface),而不是混凝土工厂,同样用于模拟测试目的)。

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

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

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

但很明显,我们随后失去了缓存等长期存在的上下文的任何潜在好处。但如果需要,还有许多其他缓存替代技术。

一个警告:DbContext 根本不是线程安全的 - 如果您使用 TPL,请确保每个任务都获得自己的 DbContext 实例 - 例如使用 Parallel.For/ForEachlocalinit 重载来实例化它。

关于c# - EF6 DbContext IOC 依赖,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27864702/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com