C# – User and role modeling

asp.netcentity-frameworkobject-orientedobject-oriented-design

I'm working with a system in ASP.NET MVC, with Entity Framework for ORM. The application has a requirements to allow users to have different types of roles, and authorization rules will be different for each role (.e.g. user with role A will be able to see some pages, role B will see some different pages)

In most of the systems that I work with before, this user and role relation will be modeled as:

public class User
{
    //Omitted properties
    public List<Role> Roles { get; set; }
}

public class Role
{
    //Omitted properties
}

However in this system, there are some other requirements that require user to have different properties based on different roles, .e.g. role A user will have property A + B, role B user will have property C + D. Each user, regardless of which role it has, is still be identified by a common id (Active Directory user id). And there might be a situation where an user has more than one role

I'm wondering what's the best way to model this relation. I think of some ways but haven't found one that is good enough:

Approach 1: Each user has a profile that contains properties that are different from role to role:

public class User
{
    //Omitted properties
    public List<Role> Roles { get; set; }
    public List<UserProfile> Profile { get; set; }
}

public abstract class UserProfile
{
    //Common properties
}

public class RoleAUserProfile : UserProfile
{
    //Omitted properties
}

public class RoleBUserProfile : UserProfile
{
    //Omitted properties
}

public class Role
{
    //Omitted properties
}

Problems: difficult to model with EF code first fluent api. I setup with table splitting approach but always have problem with abstract UserProfile and key. Also list of user profiles in User is not clear. When I want to get data for a specific role, need to loop through the list, check one by one

Approach 2: Different user class for different type of role:

public class User
{
    //Omitted properties
    public List<Role> Roles { get; set; }
}

public class RoleAUser : User
{
    //Omitted properties
}

public class RoleBUser : User
{
    //Omitted properties
}

public class Role
{
    //Omitted properties
}

Problems: cannot handle case one user multiple roles. Also the inheritance relationship seems awkward to me

Approach 3: Put everything in one User class:

public class User
{
    //Omitted properties

    //Role A properties

    //Role B properties

    public List<Role> Roles { get; set; }
}

public class Role
{
    //Omitted properties
}

Problems: difficult to maintain when number of properties for each role is large, difficult to use (need to know what properties belong to which roles to use correctly)

Approach 4: Similar to approach 1 but instead of creating new UserProfile, put data directly into different role class itself. Seem awkward to me

Any suggestion to how to model this situation? Maybe I over-complicate things but I haven't found any satisfying solution yet.

Best Answer

If a property is dependent only on the User, then it belongs on User; if it depends only on a Role, it belongs on Role. Clearly, if it depends on both User and Role, it belongs on a class that models the intersection of User and Role, i.e. something like Profile. A user can have many profiles; many profiles can refer to the same role, so it's just a normal many-to-many intersection entity.

Related Topic