我尝试实现业务层(服务层)以及存储库层。所以我的项目有以下层EF< --- Repository< --- Service< --- Controller< --- View。
我的上下文类看起来像:
public class ToDoContext : DbContext
{
public ToDoContext()
: base("ToDoContext")
{
}
public virtual DbSet<Project> Projects { get; set; }
public virtual DbSet <Collaborator> Collaborators { get; set; }
public virtual DbSet<ActionTask> Tasks { get; set; }
}
我的ProjectRepository看起来像:
public class ProjectRepository : IProjectRepository, IDisposable
{
ToDoContext Context;
public ProjectRepository(ToDoContext context)
{
this.Context = context;
}
public virtual List<Project> AllProjects()
{
IQueryable<Project> projects = Context.Projects;
return projects.ToList<Project>();
}
public Project Find(int? id)
{
// some code
}
public void InsertOrUpdate(Project project)
{
// some code
}
public void Delete(int? id)
{
// some code
}
public void Save()
{
// some code
}
public void Dispose()
{
Context.Dispose();
}
}
我的ProjectService类看起来像:
public class ProjectService : IProjectService
{
IProjectRepository ProjectRepo;
ICollaboratorRepository CollaboratorRepo;
public ProjectService(IProjectRepository projectRepo, ICollaboratorRepository collaboratorRepo)
{
this.ProjectRepo = projectRepo;
this.CollaboratorRepo = collaboratorRepo;
}
public List<Project> GetAllProjects()
{
return ProjectRepo.AllProjects();
}
public void CreateProject(FormCollection formData)
{
// code to parse form data as per my business needs
// code to code to fetch related collaborator list
// save the project data
}
public List<Collaborator> GetCollaborators(string[] collaboratorId)
{
// Fetch collaborator list using collaborator repository
return CollaboratorRepository.GetAllCollaborators();
}
}
同样,我已经为我的协作者实现了服务和存储库层。
总结代码我在ProjectService类中的 CreateProject()方法使用协作者存储库获取协作者列表,并创建一个新项目,将协作者列表与此新创建的项目相关联并保存。所以我猜我这整个过程是一个工作单元。
当我使用CollaboratorRepository获取协作者列表并尝试使用ProjectRepository保存新创建的项目时,它会抛出错误“实体对象不能被多个IEntityChangeTracker实例引用。”。我想这是因为尚未处理CollaboratorRepository dbcontext。所以我在使用新上下文之前手动处理每个上下文。我知道我无法负担手动处理上下文的开销。有人可以帮帮我吗?
我知道我应该为一个工作单元使用相同的dbcontext对象。但是当dbcontext对象暴露给存储库而不是服务层时,我不知道如何实现这一点。
答案 0 :(得分:1)
IoC如何配置?您应该按照Request \ Thread注册DbContext的LifeTime,以便为每个业务事务获取相同的实例。
提示:为了在Web环境之外拥有可重用的服务,请不要将FormCollection传递给CreateProject方法。解析FormCollection应该由controller \ model binder完成。
对于 Ninject ,请尝试InRequestScope
kernel.Bind<ToDoContext>().To<ToDoContext>().InRequestScope();