I'm developing some test web-project for my self to learn DDD and good architectural practice at all. So application, basically, is a simple photo manager.
I'm developing 3-tier architecture and for now I have:
- DAL:
- EF database first
- UserRepository
- PhotoRespoitory
- UnitOfWork
-
BLL
- UserService: user registration, authentication, registration
- PhotoService: photo retrieving, uploading, updating
- DTO Models: User, Photo, Album
- Automapper: mapping DAO from EF to DTO model
-
Asp.Net MVC Client
Here are examples of DTO models:
public abstract class ModelBase
{
public virtual long Id { get; protected set; }
}
public class User : ModelBase
{
public string Name { get; set; }
public string Email { get; set; }
public UserRole UserRole { get; set; }
public DateTime RegistrationDate { get; set; }
public override string ToString()
{
return $"{Name} {Email} {UserRole} {RegistrationDate}";
}
}
public class Photo : ModelBase
{
public string Name { get; set; }
public DateTime DateTaken { get; set; }
public string Place { get; set; }
public string CameraModel { get; set; }
public string FocalLength { get; set; }
public string Diaphragm { get; set; }
public string ShutterSpeed { get; set; }
public string ISO { get; set; }
public bool? FlashMode { get; set; }
public long OwnerId { get; set; }
public string OwnerName { get; set; }
public long AlbumId { get; set; }
public string AlbumName { get; set; }
}
So my questions are:
-
Does it make sense to create domain models with some logic, as model manipulation logic was delegated to service?
-
Is BLL the right place for DTO models?
-
Do I need to create an additional
ApplicationService
that will containPhotoService
andPhotoService
and finds user that uploads picture and then pass theUserDto
withPhotoDto
toPhotoService
?
Best Answer
You haven't really specified what you mean by "domain model". This definition is important as some developers consider their database entities as their domain model, whereas others keep a separate domain project which contains the interfaces and base classes that are inherited/implemented by actual DAL/BLL layers.
public string FullName => FirstName + LastName;
) but no actual logic.This question is a bit too open-ended for a direct answer. Some developers maintain an anemic model where data classes and logic classes are strictly separate. Other developers argue that this is against OOP principles.
I'm not making a decision here pro/anti anemic. Either approach has its benefist. And, if we're being honest, the majority of developers are expected to follow their tech lead/senior's preferred approach anyway.
Technically, every layer needs its own DTOs. But I think most people agree that the effort to do so does not outweigh the benefits.
If you only have one DTO layer, the business layer is the place to put them. Essentially, the rule of thumb is that your database entities do not leak outside of your BLL.
I wouldn't call it
ApplicationService
. But it can be meaningful to have a service named after a function rather than an entity.For example, the
UserService
handles user CRUD, theRoleService
handles role CRUD, but theAuthorizationService
handles the combination of the two: logins, resolving permissions, ... And it reuses logic fromUserService
/RoleService
where relevant.It would make little sense to put the login/permission logic in either the
UserService
orRoleService
since it so heavily depends on both. Developers would disagree with its location or, even worse, start mixing them.I think the shortest direct answer to your question is that services don't need to point to a particular database entity.