Dictionaries matter !
At first I was thinking like qwerty_so, except that:
- there is a qualified association with
UserProfiles
: it is implemented with with an IDictionary
, where a string
is used to qualify the User
.
- this association is navigable in one direction, since you can go easily from the
User
to UserProfile
, but it's much more difficult to go the other way round (you can, but you have to iterate through all the uses).
So the diagram could look like:
Some additional remarks about this diagram:
- There is no UML standard for C# properties, which are a mixture between an UML property and an UML operation (via the implicit getter and setter). The usual practice is to use an UML profile that defines the stereotype
«property»
. My own preferred option is to keep it in the properties of the class (like here or here), since that is the semantic of a C# property. However, some argue that this stereotype should be considered as a specialisation of an UML operation (like here and in qwerty's answer), which is also a valid argument, especially if you define custom getters and setters.
- Be careful with the multiplicity in qualified association, since it applies to the
User
qualified with the string. So 0..1 UserProfile is for one specific combination of User and string. So it is in reality 0..* if we would consider the unqualified User
.
Model transformation
We have to keep in mind that a given implementation could correspond to different designs. The implementation is how you write the code, and the design is how you see the things.
So we can transform this first reversed engineered model to match your thought model. Only you can tell how you want to see the things that led you to your current implementation.
For example, you may not be so interested in navigability, and you may set the focus on the many-to-many association between the unqualified User
and UserProfile
. With this approach, the string that was used as qualifier would become a property of the association class:

Be aware nevertheless that it's a transformation. Qualified association and one-to-many is not the same thing and the two models do not mean exatly the same thing.
And here comes the n-ary association !
Now the key question is the purpose of the string property in this association class. I strongly suspect that it's in fact the id
of your Application
(I let you confirm in the comments).
If it's the case, we would have an association between the association class and the Application
. And we could remove the string property from the association class because it would then be redundant.
But an association class that is itself associated with some other class, shows that there in fact an n-ary associaton (ternary here). So, we could make this explicit:

Now you have an n-ary association. You could even have an association class behind it, if there would be additional properties to associate with each triplet (User, Application, UserProfile).
But be aware that this diagram is less precise. It is for example more difficult to indicate navigability constraints in an n-ary association. And it does no longer fully correspond to your implementation: this model suggest that you could find users starting from an application, whereas in your implementation it's more difficult.
Conclusion/advices
Personally, I find n-ary association difficult to work with and I prefer to decompose them in a set of classes and binary associations (and association classes when necessary): This allows to remove a lot of ambiguity and gives tighter control. I can only recommend you the same approach.
Consider also your implementation: if the implementation represents your view of the world, then use the qualified association, because it's the UML equivalent to the dictionary.
However if the ternary association is your view of the world, you may sooner or later have to review your current implementation. Probably you'd extract the profiles to make an own class of it.