我有一个解决方案,使用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; }
}
}
在你上面的评论可以看到,我觉得我“应该”犯我的变化,但我觉得我可能通过允许服务层和存储库实现来控制事务的范围,从而忽略了更大的问题。
此外 - 当我的存储库需要保存一个新的对象,并返回新的给定的主键完好无损时,如果我在对象返回后从UI调用Commit,则不会发生这种情况。因此,存储库有时需要管理工作单元。
你能看到我的方法有任何直接的问题吗?
感谢这样一个发人深省的答复。我的逻辑操作的边界不应该由UI开发人员定义,这促使我质疑当前的方法。大部分UI工作将由初级开发人员完成,对业务领域知之甚少,所以我们希望尽可能少地提出问题。由于我们可能需要构建多个实现,因为我们需要存储库层非常“愚蠢”,因为某些客户可能非常希望使用基于其他平台的存储解决方案,因此服务层是必需的。 – Baldy 2011-06-04 16:21:46