问题描述
|
我正在使用nHibernate编写ASP.Net Webforms应用程序。目前,我没有使用任何IoC框架。
首先,我的场景:
我不想允许两个雇员同名。我想使Employee类能够搜索具有相同名称的其他Employee并发出一个错误。
一个部门可能有数千名员工。我需要确切地知道每个部门有多少名员工。我不想将它们全部加载到内存中,因此我使用了计算所得的属性-EmployeesCount。但是,此属性在第一次加载Department对象时被初始化。如果我添加/删除员工,则更改不会反映在该属性中。 (特别是因为我使用的是二级缓存,所以我的对象在多个Session范围内都保持不变)
解决这些问题的想法是让我的域对象引用适当的存储库对象。
我认为最好的解决方案是让我的存储库实现接口并使用某种IoC容器/ DI机制。
因此,在Employee中,我将拥有:
if (_empRepository.GetEmployeeByName(newEmployeeName) != null) //...
在部门:
public int EmployeesCount
{
get
{
return _departmentRepository.GetCurrentEmployeesCount(this);
}
}
我的问题:
哪个是可取的?
公共Employee(IEmployeeRepository存储库)
或使用IoC容器?
public Employee()
{
_empRepository = container.Resolve<IEmployeeRepository>();
}
如何实施所需的解决方案?我知道拦截器/切碎机是必经之路,但我无法真正掌握整个过程。这是一个好例子吗?另外-我应该在哪个命名空间中定义接口,IoC容器等?
解决方法
POC0与持久性之间的关系通常是单向的:持久性层了解POCO,但并非相反。
当您让POCO负责诸如搜索具有相同名称的其他员工之类的事情时,便使其成为双向的。我会担心设计中模块之间的增长周期。
将该活动放在POCO中听起来不错,因为它有助于避免使用“贫血领域模型”标签,但我不会这样做。我将这些方法放在持久性接口上,让它们处理。负责实现用例的服务也更有可能希望了解重复的Employee名称;让它进行询问,将POCO排除在对话之外。
这种方法将使您的测试生活更加轻松。您将知道测试时模块的痛苦程度。您必须将过多的设备拖入测试中才能使其正常工作。
, 我还认为Pocos不应该了解持久性。您是否考虑过类似的替代方案
class Department
{
public int Id { get; set; }
public IList<Employee> ActiveEmployees { get; set; }
}
public DepartmentMap()
{
...
HasMany(d => d.ActiveEmployees)
.KeyColumn(\"department_id\")
.Where(\"stillactiveindepartment = true\") // for example
.ExtraLazyLoad(); // will issue an Count(*) instead of initializing collection,also other methods like Contains() issue an sql
}
对于具有唯一名称的员工:
1)在服务/控制器中:在保存新员工之前,发出查询以检查是否存在同名员工。
2)数据库中的唯一约束将在保存时给出异常。
3)会话中的自定义拦截器,它钩住保存/刷新事件。如果已经有客户,它会抛出
, 另一个答案主要是解决您提出的问题,我同意那里的建议。
对于有关访问员工人数的问题,请考虑将预测与NHibernate一起使用。我将在您的服务层中使用一个计数预测来查询(对于任何Web服务操作需要获取员工人数)。
编辑:忘记您正在使用服务/存储库/ POCO。在这种情况下,请在存储库中创建员工人数查询,然后从服务中调用它。