In Domain Driven Design literature it is often said that domain services should be stateless.
I believe the reason for this is because service calls should represent single units of work. There shouldn't be any service state which multiple service methods would use.
I break this rule in my service architecture so that I can constructor inject all the relevant repositories required in the service. Example:
public class UserService : IUserService
{
public IUnitOfWork UnitOfWork { get; set; }
public IUserRepository UserRepository { get; set; }
public ICustomerRepository CustomerRepository { get; set; }
public UserService(IUnitOfWork unitOfWork, IUserRepository userRepository, ICustomerRepository customerRepository)
{
UnitOfWork = unitOfWork;
UserRepository = userRepository;
CustomerRepository = customerRepository;
}
public User RegisterNewUser(...)
{
// Perform relevant domain logic
}
// ...
}
In order for me to use constructor injection on the UserService
, I would need to have state (properties) so that the service methods have access to the relevant repositories and such.
Although I hope to design the individual service methods as isolated units of work, I cannot necessarily prevent that from happening.
How could I architecture domain services so that they are stateless? Is this even necessary?
EDIT:
Eric Evans in Domain-driven Design: Tackling Complexity in the Heart of Software:
When a significant process or transformation in the domain is not a natural responsibility of an ENTITY or VALUE OBJECT, add an operation to the model as standalone interface declared as a SERVICE. Define the interface in terms of the language of the model and make sure the operation name is part of the UBIQUITOUS LANGUAGE. Make the SERVICE stateless.
Vaughn Vernon also recommends stateless services in his book Implementing Domain Driven Design.
One way to get close to your goal is to inject an IOC container into your service class then override your property get methods to resolve an instance of the necessary class. Your new class would look something like this:
public class UserService : IUserService
{
private IUnitOfWork UnitOfWork
{
get{return container.Resolve<IUnitOfWork>()}
}
private IUnityContainer container {get;set;}
public UserService(IUnityContainer container )
{
this.container = container;
}
public User RegisterNewUser(User user)
{
//Domain logic
}
}
Your service class now has a dependency on an IOC container which is not a good thing, but if you are trying to get closer to a stateless service, this would do it.