我有一個解決方案,使用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