6
votes

We are trying to model an RBAC-based user maintenance system using DDD principles. We have identified the following entities:

Authorization is an Aggregate Root with the following:
    User   (an entity object)
    List<Authority>    (list of value objects)

Authority contains the following value objects:
    AuthorityType (base class of classes Role and Permission)
    effectiveDate

Role contains a List<Permission>
Permission has code and description attributes

In a typical scenario, Authorization is definitely the Aggregate Root since everything in user maintenance revolves around that (e.g. I can grant a user one or more Authority-ies which is either a Role or Permission)

My question is : what about Role and Permission? Are they also Aggregate Roots in their own separate contexts? (i.e. I have three contexts, authorization, role, permission). While can combine all in just one context, wouldn't the Role be too heavy enough since it will be loaded as part of the Authorization "object graph"?

1

1 Answers

36
votes

Firstly I can't help but feel you've misunderstood the concept of a bounded context. What you've described as BC's I would describe as entities. In my mind, bounded contexts serve to give entities defined in the ubiquitous language a different purpose for a given context.

For example, in a hospital domain, a Patient being treated in the outpatients department might have a list of Referrals, and methods such as BookAppointment(). A Patient being treated as an Inpatient however, will have a Ward property and methods such as TransferToTheatre(). Given this, there are two bounded contexts that patients exist in: Outpatients & Inpatients. In the insurance domain, the sales team put together a Policy that has a degree of risk associated to it and therefore cost. But if it reaches the claims department, that information is meaningless to them. They only need to verify whether the policy is valid for the claim. So there is two contexts here: Sales & Claims

Secondly, are you just using RBAC as an example while you experiment with implementing DDD? The reason I ask is because DDD is designed to help solve complex business problems - i.e. where calculations are required (such as the risk of a policy). In my mind RBAC is a fairly simple infrastructure service that doesn't concern itself with actual domain logic and therefore doesn't warrant a strict DDD implementation. DDD is expensive to invest in, and you shouldn't adopt it just for the sake of it; this is why bounded contexts are important - only model the context with DDD if it's justifiable.

Anyway, at the risk of this answer sounding to 'academic' I'll now try to answer your question assuming you still want to model this as DDD:

To me, this would all fit under one context (called 'Security' or something)

As a general rule of thumb, make everything an aggregate that requires an independent transaction, so:

  1. On the assumption that the system allows for Authorities to be added to the Authorization object, make Authorization an aggregate. (Although there might be an argument for ditching Authorization and simply making User the aggregate root with a list of Authorities)
  2. Authorities serve no meaning outside of the Authorization aggregate and are only created when adding one, so these remain as entities.
  3. On the assumption that system allows for Permissions to be added to a Role, Role becomes an aggregate root.
  4. On the assumption that Permissions cannot be created/delete - i.e. they are defined by the system itself, so these are simple value objects.

Whilst on the subject of aggregate design, I cannot recommend these articles enough.