views:

170

answers:

1

I'm trying to do things the DDD (domain driven design) way. And boy do I struggle. In all books I read, Authentication is of no concern and not mentioned!

I've written my own Authentication and Membership Service which are responsible for registering and logging in users, creating salted passwords etc. I do not use .NET's Membership Provider but do rely on Forms Authentication.

I've implemented a User model that holds the Username, E-Mail, PasswordHash, ApprovalStatus etc.

Now I guess the rest of the domain model shouldn't concern itself with the Users. I have a class Person that is used to model Persons and their associated data. As such it can be used to model personal data from users and from non-users. An object of type Company works with Persons, not Users. And an Activity is assigned to a Person, not a User.

The question, how do I relate the Person model to the User model? I don't really want a reference to each other in either of the two models. Should I create some Relationship model called PersonUser and create an additional service that retrieves the person object for the currently authenticated user?

+1  A: 

Judging from what you've presented, you've got a couple of known facts:

  1. Every User is a Person
  2. Not every Person is a User

That being the case, I would expand the person model to include a nullable UserId field so that you can relate the User to the Person for those Persons that are also users.

Now I'm also going to assume that you have several "Fetch" methods in the person model.. to retrieve a person by ID, Name, Department, etc...

I would overload (or create a different) fetch method to also retrieve the person object from a User as well (this can be either an id, or the foll user object).

public IPerson Fetch(IUser user) {}

Of course, since you have the known fact that every user is also a person, I personally see no harm nor foul in expanding the user object to include a person property...

public interface IUser 
{
   ...
   IPerson Person { get; set; }
}

Then, you can return the user object as always.. and perhaps do some funky lazy loading of the person field in the user... or populate both when you fetch the user object.

I'm not sure if creating a "mapping" table of User <-> Person is going to garner you much of anything beyond what I've outlined above (although you will get kudo's from the hardcore DBA's for denormalizing your data).. to me it's just an extra table to join to to get the same effect.

datacop
I won't do it that way, but thanks for your input. I've decoupled my User from my Person model, both inside the domain model, and in my database. Accepted question since you helped me clear things up.
kitsune
Thanks for the accept.. I would be REALLY interested in hearing how you approached this and what your final solution was. I'm a firm believer in keeping an open mind and learning as many different approaches to the same problem helps everyone to become a better engineer / architect.
datacop