EF ObjectContext,Service and Repository – 管理上下文生命周期。

我是MVP和entity framework世界的新手,所以请耐心等待。

我目前有一个View + Presenter组合,视图有两个事件Edit和Delete,演示者只是监听这些事件。 我还有一个服务对象和存储库设置。 服务层采用一些存储库实现,这些实现采用ObjectContext,因此构造的顺序是(将顶层对象传递给它下面的对象:

ObjectContext | V Repositries | V Service Object | V Presenter 

现在的问题是,当我在顶部创建对象上下文时,它一直存在,演示者处于活着状态,这意味着编辑和删除使用来自服务的相同上下文实例。

因此,调用ServiceObject.Delete和ServiceObject.Edit会使用相同的上下文,这使得很难管理更改跟踪。 根据我的理解,上下文应该只是短暂的,只有一个工作单元,对我来说编辑和删除都是不同的工作。

您如何使用entity framework进行DI并仍然管理上下文生命周期?

我看到人们刚刚在存储库中新建了对象上下文,这是一个很好的模式。

或者我应该在服务对象中执行此操作,例如:

 ServiceObject{ public void Edit(// some args) { Using(var context = new MyObjectContext) { var repo = new MyRepo(context); var entity = repo.GetForID(12); // Do some stuff for edit context.SaveChanges(); } } } 

但是,如果我这样做,我不再将我的存储库传递给ServiceObject的构造函数而不执行DI :(。

在这种情况下我该怎么办?

有谁知道我可以看到的任何开源项目可以帮助我解决这个问题。

谢谢。

我将从顶部(演示者)开始,描述参与者之间的关系。

Presenter通过依赖获取服务对象。 使用合同概述服务function:

 class Presenter { public Presenter(IService service) { ... } } 

从特定数据访问层实现中抽象出服务实现。 基本上,每当服务执行一些需要数据源交互的操作时,它就会创建一个工作单元的实例,并在完成时将其处理掉。

 interface IService { void Do(); } class Service : IService { private readonly IUnitOfWorkFactory unitOfWorkFactory; public Service(IUnitOfWorkFactory unitOfWorkFactory) { this.unitOfWorkFactory = unitOfWorkFactory; } public void Do() { // Whenever we need to perform some data manipulation we create and later dispose // dispose unit of work abstraction. It is created through a factory to avoid // dependency on particular implementation. using(IUnitOfWork unitOfWork = this.unitOfWorkFactory.Create()) { // Unit of work holds Entity Framework ObjectContext and thus it used // create repositories and propagate them this ObjectContext to work with IRepository repository = unitOfWork.Create(); repository.DoSomethingInDataSource(); // When we are done changes must be commited which basically means committing // changes of the underlying object context. unitOfWork.Commit(); } } } ///  /// Represents factory of  implementations. ///  public interface IUnitOfWorkFactory { ///  /// Creates  implementation instance. ///  /// Created  instance. IUnitOfWork Create(); } ///  /// Maintains a list of objects affected by a business transaction and coordinates the writing out of /// changes and the resolution of concurrency problems. ///  public interface IUnitOfWork : IDisposable { ///  /// Creates and initializes repository of the specified type. ///  /// Type of repository to create. /// Created instance of the repository. ///  /// Created repositories must not be cached for future use because once this ///  is disposed they won't be able to work properly. ///  TRepository Create(); ///  /// Commits changes made to this . ///  void Commit(); } ///  /// Represents factory of s. ///  public class UnitOfWorkFactory : IUnitOfWorkFactory { private readonly IUnityContainer container; ///  /// Initializes a new instance of the  class. ///  ///  /// Dependency injection container instance used to manage creation of repositories /// and entity translators. ///  public UnitOfWorkFactory(IUnityContainer container) { this.conainer = container; } ///  /// Creates  implementation instance. ///  /// Created  instance. public IUnitOfWork Create() { var unitOfWork = this.container.Resolve(); unitOfWork.SetupObjectContext(); return unitOfWork; } ... other members elidged for clarity } 

IUnitOfWork的实现接收IUnityContainer的实例,然后创建子容器并在那里注册ObjectContext实例。 此子容器将用于创建存储库并传播ObjectContext。

这是IUnitOfWork的简化实现:

 class UnitOfWork : IUnitOfWork { private readonly IUnityContainer container; private ObjectContext objectContext; public UnitOfWork (IUnityContainer container) { this.container = container.CreateChildContainer(); } public void SetupObjectContext() { this.objectContext = ... // Create object context here this.container.RegisterInstance(context.GetType(), context); } public void Create() { // As long as we registered created object context instance in child container // it will be available now to repositories during resolve return this.container.Resolve(); } public void Commit() { this.objectContext.SaveChanges(); } } class Repository : IRepository { private readonly SomeObjectContext objectContext; public Repository(SomeObjectContext objectContext) { this.objectContext = objectContext; } public void DoSomethingInDataSource() { // You can use object context instance here to do the work } }