【发布时间】:2011-09-08 08:52:40
【问题描述】:
我有一个解决方案,将 webforms 用于前端,将 mvc 用于管理控制台。
两个 UI 都通过 Ninject 使用服务层,我无法解决一个微妙但相当重要的问题。
假设我有一个 CourseService,它根据字符串搜索词返回课程列表 - 该服务返回搜索结果,但我还需要记录进行的搜索以及与该词匹配的课程数量,以便管理信息目的。
我一开始的想法是,工作单元将由 UI 提交,在请求结束时,在页面方法中,例如按钮单击事件。这同样适用于控制器。
这里的问题是我依赖 UI 开发人员调用工作单元上的 Commit() 以便记录搜索。 UI 开发人员无需调用 commit 就可以愉快地继续工作,并且会返回结果——但不会记录搜索。这导致我决定让服务层控制工作单元的范围。 Ninject 会自动将工作单元传递给服务层和存储库实现,这将与我告诉 ninject 根据请求范围创建它实际上是同一个实例。
这是我的层是如何编写的示例...
public class CourseService
{
private readonly ICourseRepository _repo;
public CourseService(ICourseRepository repo)
{
_repo = repo;
}
public IEnumerable<Course> FindCoursesBy(string searchTerm)
{
var courses = _repo.FindBy(searchTerm);
var log = string.format("search for '{1}' returned {0} courses",courses.Count(),searchTerm);
_repo.LogCourseSearch(log);
//IMO the service layer should be calling Commit() on IUnitOfWork here...
return courses;
}
}
public class EFCourseRepository : ICourseRepository
{
private readonly ObjectContext _context;
public EFCourseRepository(IUnitOfWork unitOfWork)
{
_context = (ObjectContext)unitOfWork;
}
public IEnumerable<Course> FindBy(string text)
{
var qry = from c in _context.CreateObjectSet<tblCourse>()
where c.CourseName.Contains(text)
select new Course()
{
Id = c.CourseId,
Name = c.CourseName
};
return qry.AsEnumerable();
}
public Course Register(string courseName)
{
var c = new tblCourse()
{
CourseName = courseName;
};
_context.AddObject(c);
//the repository needs to call SaveChanges to get the primary key of the newly created entry in tblCourse...
var createdCourse = new Course()
{
Id = c.CourseId,
Name = c.CourseName;
};
return createdCourse;
}
}
public class EFUnitOfWork : ObjectContext, IUnitOfWork
{
public EFUnitOfWork(string connectionString) : base(connectionString)
{}
public void Commit()
{
SaveChanges();
}
public object Context
{
get { return this; }
}
}
在上面的 cmets 中,您可以看到我觉得我“应该”在哪里提交我的更改,但我觉得通过允许服务层和存储库实现来控制事务的范围,我可能忽略了一个更大的问题。
除此之外 - 当我的存储库需要保存一个新对象并完整返回新给定的主键时,如果我在对象返回后从 UI 调用 Commit,则不会发生这种情况。所以仓库有时确实需要管理工作单元。
你能看出我的方法有什么直接的问题吗?
【问题讨论】:
标签: architecture repository-pattern ninject unit-of-work service-layer