0
votes
public class PageRoleService
{
    public void SetRoles(Page page, User activeUser)
    {
        var rb = page.Project.ProjectType.GetRoleFor(activeUser.UserType);

        page.RolesForPage.Add(activeUser, rb);
        var managers = GetAllManagersOf(activeUser);
        foreach (var m in managers)
        {
            page.RolesForPage.Add(m, rb);
        }
    }
}

public class Project : Entity
{
    public ProjectType ProjectType { get; set; }
    public IList<Page> Pages { get; set; }
}

public class Page : Entity
{
    public string Name { get; set; }
    public Project Project { get; set; }
    public IDictionary<User, RoleBehaviour> RolesForPage { get; set; }
}

public class ProjectType : Entity
{
    public IQueryProcessor QueryProcessor { get; set; }

    public IList<RoleBehaviour> RoleBehaviours { get; set; }

    public RoleBehaviour GetRoleFor(USerType userType)
    {
        var behaviour = return QueryProcessor.Execute(new GetRolesByUserAndProjectTypeQuery() {
        ProjectType = this,
        UserType = userType
    });

    // Filter behaviour attributes for project type properties, business rules, etc...
    // FilterBehaviour(behaviour);
    return behaviour;
  }
}

public class GetRolesByUserAndProjectTypeQuery
{
    public UserType UserType { get; set; }
    public ProjectType ProjectType { get; set; }
}


public class GetRolesByUserAndProjectTypeQueryHandler
{
    public Db Db { get; set; }
    public RoleBehaviour Execute(GetRolesByUserAndProjectTypeQuery query)
    {
        return Db.FirstOrDefault(r => r.UserType == query.UserType && r.ProjectType == query.projectType);
    }
}

public class RoleBehaviour : Entity
{
    public Role ROleForArea1 { get; set; }
    public Role ROleForArea2 { get; set; }
    public UserType UserType { get; set; }
    public ProjectType ProjectType { get; set; }
    public IDictionary<string, string> Attributes { get; set; }
}

public enum UserType
{
    A,
    B,
    C,
    D
}

public class Role : Entity
{
    public IList<string> Permissions { get; set; }
}

I don't use repository, no need data abstraction, I use CQRS for crud operations. (CreateProjectCommand, GetRolesByUserAndProjectTypeQuery, etc..) Users related a lot of project and page. Users have more than role for each Page Entity and is dynamically created when user (client) request to fetch All projects page or single page item.

My Page Role Service determinates page roles for active user and its managers. My MVC Controller use PageRoleService.

  1. PageRoleService is Application Service or Domain Service or .....?
  2. QueryProcessor in Entity (ProjectType) is invalid approach? How can handle this/their problems without lazy or eager loading?
  3. RoleBehaviour is Entity or Value Object?
  4. PageRoleService is a service or business logic in domain?
1
"I use CQRS for crud operations." Why?Dennis Traub
@DennisTraub I don't use repository pattern and I preferr it instead to use data access in application service. Also my application has command-based ui.All operations are command.oguzh4n
You don't need any repositories for CRUD. And you don't need CQRS either. If the solution is more complicated than the problem you're trying to solve, than something might be slightly off.Dennis Traub
yeah I agree, I don't need repository but I need to organize queries for this reason I use CQRS like this (github.com/mravinale/Cronos) (not event sourcing) CQRS Commands are represent Application Service?oguzh4n
The command handler represents the application service, commands themselves represent calls to the application service.Dennis Traub

1 Answers

0
votes

I know that I'm some years later, but:

I would put away the base class Entity, because it looks that this are just Dtos returned by the queryhandler (infact GetRolesByUserAndProjectTypeQueryHandler.Execute returns a RoleBehaviour).

Given this, I think that:

  1. PageRoleService is a simple service that completes a Dto, hence it looks a kind of factory
  2. Given that ProjectType here has two different roles (a Dto and Entity, and this is against CQRS), if:
    1. it's a Dto, then use a service/factory/ORM to load extra data on it
    2. it's an Entity, try to load all the data that's needed by it. This because there're great changes that you'll need it on the way to execute your command (great explanation about DDD and entities).
  3. The object has it's own identity? Has it an Id that, even if things will change, remains the same? Looking at it, it looks just a Dto, with nothing really interesting (at business level).
  4. see 1.