I’m writing an ASP.Net webforms app using nHibernate. Currently I’m not using any IoC framework.
Firstly- my scenarios:
-
I don’t want to allow two Employees with the same name. I would like to enable the Employee class to search for other Employee with the same name and issue an error.
-
A Department may have 1000s of Employees. I need to know exactly how many Employees each Department has. I don’t want to load them all into memory, so I use a calculated property- EmployeesCount. However, this property is initialized the first time the Department object is loaded. If I add / remove employees the changes are not reflected in that property. (especially since I’m using 2nd level cache, so my object persists over multiple Session scopes)
My idea of solving these problems is to have my domain objects hold reference to the appropriate Repository objects.
I think the best solution is to have my repositories implement interfaces and use some sort of IoC container / DI mechanism.
So, in Employee I’ll have:
if (_empRepository.GetEmployeeByName(newEmployeeName) != null) //...
and in Department:
public int EmployeesCount
{
get
{
return _departmentRepository.GetCurrentEmployeesCount(this);
}
}
my questions:
-
Which is prefferable- c’tor DI
public Employee(IEmployeeRepository repository)
or using an IoC container?
public Employee()
{
_empRepository = container.Resolve<IEmployeeRepository>();
}
- How to implement the desired solution? I understand that Interceptors / tuplizers is the way to go, but I couldn’t really get my head around the whole thing. Is this a good example? Also- in which namespace should I define the Interfaces, the IoC container etc.?
The POC0-to-persistence relationship is usually uni-directional: The persistence tier knows about POCOs, but not the other way around.
The moment you make the POCO responsible for things like searching for other Employees with the same name, you make it bi-directional. I’d be concerned about growing cycles between modules in your design.
Putting that activity in the POCO might sound like a good idea, because it helps to avoid the “anemic domain model” label, but I wouldn’t do it. I’d put those methods on persistence interfaces and let them handle it. It’s also more likely that the service in charge of fulfilling the use case would want to know about duplicate Employee names; let it do the asking and leave POCO out of the conversation.
This approach will make your testing life easier. You’ll know how painful module cycles can be when you go to test. You’ll have to drag too much machinery into the test to get it to work.