Just created an acc on SO to ask this :)
Assuming this simplified example: building a web application to manage projects...
The application has the following requirements/rules.
1) Users should be able to create projects inserting the project name.
2) Project names cannot be empty.
3) Two projects can't have the same name.
I'm using a 4-layered architecture (User Interface, Application, Domain, Infrastructure).
On my Application Layer i have the following ProjectService.cs class:
public class ProjectService
{
private IProjectRepository ProjectRepo { get; set; }
public ProjectService(IProjectRepository projectRepo)
{
ProjectRepo = projectRepo;
}
public void CreateNewProject(string name)
{
IList<Project> projects = ProjectRepo.GetProjectsByName(name);
if (projects.Count > 0) throw new Exception("Project name already exists.");
Project project = new Project(name);
ProjectRepo.InsertProject(project);
}
}
On my Domain Layer, i have the Project.cs class and the IProjectRepository.cs interface:
public class Project
{
public int ProjectID { get; private set; }
public string Name { get; private set; }
public Project(string name)
{
ValidateName(name);
Name = name;
}
private void ValidateName(string name)
{
if (name == null || name.Equals(string.Empty))
{
throw new Exception("Project name cannot be empty or null.");
}
}
}
public interface IProjectRepository
{
void InsertProject(Project project);
IList<Project> GetProjectsByName(string projectName);
}
On my Infrastructure layer, i have the implementation of IProjectRepository which does the actual querying (the code is irrelevant).
I don't like two things about this design:
1) I've read that the repository interfaces should be a part of the domain but the implementations should not. That makes no sense to me since i think the domain shouldn't call the repository methods (persistence ignorance), that should be a responsability of the services in the application layer. (Something tells me i'm terribly wrong.)
2) The process of creating a new project involves two validations (not null and not duplicate). In my design above, those two validations are scattered in two different places making it harder (imho) to see whats going on.
So, my question is, from a DDD perspective, is this modelled correctly or would you do it in a different way?