Question

I'm learning about domain driven design and I'm a little bit confused about the place where I should put my business rules. Let's say that I have an aggregate root named Member which holds reference to entity Password. Password looks like this:

public class Password
{
    public string Hash { get; private set; }
    public string Salt { get; private set; }
    public DateTime ExpirationDate { get; private set; }

    public void GenerateNewPassword(string plainPassword)
    {
        //Some logic here
    }
}

I also have a settings object named Settings. Settings are loaded from settings repository. This object has reference to another object named PasswordRules. Password rules of course checks password requirements within method CheckPasswordRequirements:

public bool CheckPasswordRequirements(string password)
{
    //Some logic here
}

So my question is, is it the best place to hold this password rules or should I move this method to Password class as it is password object responsibility to check if given plain password meets requirements (then I should also put settings repository in Password entity) or should this check be done directly in the service that is creating member objects? And maybe there is some other elegant solution?

Was it helpful?

Solution 2

There's no definite answer that can be derived from the business logic. Both approaches are equally valid. I'd take a more pragmatic view:

  • If your password checking algorithm is simple then I would place the CheckPasswordRequirements method directly in the Password class and call it in the c'tor.
  • If the algorithm is more complex or will possibly be subject to change in the future, then you're better of with a separate Utility class (named something like PasswordChecker). As a variant, you could also do this in form of an extension method:

static class PasswordExtension
{
    public static bool CheckPasswordRequirements(this string password)
    {
        //Some logic here
    }
}

OTHER TIPS

From a DDD point of view, if the password check is going to involve more than the Password entity, then is should be placed in a domain service. These can be placed alongside your entities in the relevant namespace in your domain model.

If it's a wider process that includes many steps at a higher application level (and particularly if the process is not a core part of your domain), then you may wish to place the functionality in an application service outside of your domain.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top