san*_*MPS 7 c# entity-framework windows-services dependency-injection visual-studio-2013
我在Windows服务/控制台应用程序中使用EF6.我已经为我的业务层接口和实现成功实现了IOC/DI.使用构造函数注入.我也在使用对象数据库,任务并行库.为了更好的表现,我很高兴.
还使用System.IO.Abstractions 使我的代码更易于测试.
EF6使用.tt文件为所有域实体创建POCO clases,非常方便.为了执行数据库查询,我写的每一个地方
using(var db = new MyContext())
{
// code reading from/writing to database
...
...
}
Run Code Online (Sandbox Code Playgroud)
我知道这不是正确的做法,并在我的代码中的各个地方发出噪音.我想让它松散耦合.现在我的数据库操作 - 我很困惑如何前进,使它更可测试和松散耦合..任何人都可以指出一个很好的例子,可以参考的文章.
我想要实现的两个主要方面是对连接字符串配置(对于各种服务器部署)有更多的控制,并且DbContext在我的代码中具有非常松散的耦合.
Stu*_*tLC 10
为了解决解耦(和测试),你可以创建自己的为你的界面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;
}
Run Code Online (Sandbox Code Playgroud)
(您也可以考虑接口的只读和读写版本)
然后改变你的具体DbContext来实现这个接口.您现在可以合理地与DbContext(用于单元测试等)脱钩,但仍然可以访问IQueryable固有工作单元和缓存提供的有用性DbContext.
然后,这里有两个注入IMyDbContext业务/服务类的选项
IDbContext要么
DbContexts,然后进行IMyDbContextFactory工厂接口的构造函数注入(你需要接口,而不是具体的工厂,再次用于Mocking测试目的).这里的选择取决于你需要做什么DbContext.在IoC容器中配置#1可能很棘手,因为您需要将生命周期管理移交给容器.但是,如果可以为每个请求配置新实例,那么这在Web应用程序中可能是有益的,因此如果请求(假设单个线程)可以将其用作缓存.
我个人更喜欢#2,因为这允许直接管理上下文:
using(var db = _myContextFactory.CreateDB())
{
db.SaveChanges();
}
Run Code Online (Sandbox Code Playgroud)
但显然,我们失去了长期环境(如缓存)的任何潜在好处.但是,如果需要,还有许多其他替代技术可用于缓存.
需要注意的是:DbContext根本不是线程安全 - 如果您使用的是TPL,请确保每个任务都获得自己的实例DbContext- 例如,使用/ 的localinit重载在使用它时实例化它.Parallel.ForForEach
| 归档时间: |
|
| 查看次数: |
3802 次 |
| 最近记录: |